{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
module Aztecs.ECS.World
( World (..),
empty,
spawn,
spawnEmpty,
insert,
insertUntracked,
lookup,
remove,
removeWithId,
despawn,
)
where
import Aztecs.ECS.Access.Internal (Access)
import Aztecs.ECS.Component
import Aztecs.ECS.Entity
import Aztecs.ECS.World.Bundle
import qualified Aztecs.ECS.World.Entities as E
import Aztecs.ECS.World.Internal (World (..))
import qualified Aztecs.ECS.World.Observers as O
import Data.Dynamic
import Data.IntMap (IntMap)
import Prelude hiding (lookup)
empty :: World m
empty :: forall (m :: * -> *). World m
empty =
World
{ entities :: Entities m
entities = Entities m
forall (m :: * -> *). Entities m
E.empty,
nextEntityId :: EntityID
nextEntityId = Int -> EntityID
EntityID Int
0,
observers :: Observers (StateT (World m) m)
observers = Observers (StateT (World m) m)
forall (m :: * -> *). Observers m
O.empty
}
spawn :: (Monad m) => BundleT m -> World m -> (EntityID, World m, Access m ())
spawn :: forall (m :: * -> *).
Monad m =>
BundleT m -> World m -> (EntityID, World m, Access m ())
spawn BundleT m
b World m
w =
let e :: EntityID
e = World m -> EntityID
forall (m :: * -> *). World m -> EntityID
nextEntityId World m
w
(Entities m
es', Access m ()
hook) = EntityID -> BundleT m -> Entities m -> (Entities m, Access m ())
forall (m :: * -> *).
Monad m =>
EntityID -> BundleT m -> Entities m -> (Entities m, Access m ())
E.spawn EntityID
e BundleT m
b (Entities m -> (Entities m, Access m ()))
-> Entities m -> (Entities m, Access m ())
forall a b. (a -> b) -> a -> b
$ World m -> Entities m
forall (m :: * -> *). World m -> Entities m
entities World m
w
in (EntityID
e, World m
w {entities = es', nextEntityId = EntityID $ unEntityId e + 1}, Access m ()
hook)
spawnEmpty :: World m -> (EntityID, World m)
spawnEmpty :: forall (m :: * -> *). World m -> (EntityID, World m)
spawnEmpty World m
w = let e :: EntityID
e = World m -> EntityID
forall (m :: * -> *). World m -> EntityID
nextEntityId World m
w in (EntityID
e, World m
w {nextEntityId = EntityID $ unEntityId e + 1})
insert :: (Monad m) => EntityID -> BundleT m -> World m -> (World m, Access m ())
insert :: forall (m :: * -> *).
Monad m =>
EntityID -> BundleT m -> World m -> (World m, Access m ())
insert EntityID
e BundleT m
c World m
w =
let (Entities m
es', Access m ()
hook) = EntityID -> BundleT m -> Entities m -> (Entities m, Access m ())
forall (m :: * -> *).
Monad m =>
EntityID -> BundleT m -> Entities m -> (Entities m, Access m ())
E.insert EntityID
e BundleT m
c (World m -> Entities m
forall (m :: * -> *). World m -> Entities m
entities World m
w)
in (World m
w {entities = es'}, Access m ()
hook)
insertUntracked :: (Monad m) => EntityID -> BundleT m -> World m -> World m
insertUntracked :: forall (m :: * -> *).
Monad m =>
EntityID -> BundleT m -> World m -> World m
insertUntracked EntityID
e BundleT m
c World m
w =
let es' :: Entities m
es' = EntityID -> BundleT m -> Entities m -> Entities m
forall (m :: * -> *).
Monad m =>
EntityID -> BundleT m -> Entities m -> Entities m
E.insertUntracked EntityID
e BundleT m
c (World m -> Entities m
forall (m :: * -> *). World m -> Entities m
entities World m
w)
in World m
w {entities = es'}
lookup :: forall m a. (Component m a) => EntityID -> World m -> Maybe a
lookup :: forall (m :: * -> *) a.
Component m a =>
EntityID -> World m -> Maybe a
lookup EntityID
e World m
w = EntityID -> Entities m -> Maybe a
forall (m :: * -> *) a.
Component m a =>
EntityID -> Entities m -> Maybe a
E.lookup EntityID
e (Entities m -> Maybe a) -> Entities m -> Maybe a
forall a b. (a -> b) -> a -> b
$ World m -> Entities m
forall (m :: * -> *). World m -> Entities m
entities World m
w
remove :: forall m a. (Component m a) => EntityID -> World m -> (Maybe a, World m, Access m ())
remove :: forall (m :: * -> *) a.
Component m a =>
EntityID -> World m -> (Maybe a, World m, Access m ())
remove EntityID
e World m
w =
let (Maybe a
a, Entities m
es, Access m ()
hook) = EntityID -> Entities m -> (Maybe a, Entities m, Access m ())
forall (m :: * -> *) a.
Component m a =>
EntityID -> Entities m -> (Maybe a, Entities m, Access m ())
E.remove EntityID
e (World m -> Entities m
forall (m :: * -> *). World m -> Entities m
entities World m
w)
in (Maybe a
a, World m
w {entities = es}, Access m ()
hook)
removeWithId :: forall m a. (Component m a) => EntityID -> ComponentID -> World m -> (Maybe a, World m, Access m ())
removeWithId :: forall (m :: * -> *) a.
Component m a =>
EntityID
-> ComponentID -> World m -> (Maybe a, World m, Access m ())
removeWithId EntityID
e ComponentID
cId World m
w =
let (Maybe a
a, Entities m
es, Access m ()
hook) = EntityID
-> ComponentID -> Entities m -> (Maybe a, Entities m, Access m ())
forall (m :: * -> *) a.
Component m a =>
EntityID
-> ComponentID -> Entities m -> (Maybe a, Entities m, Access m ())
E.removeWithId EntityID
e ComponentID
cId (World m -> Entities m
forall (m :: * -> *). World m -> Entities m
entities World m
w)
in (Maybe a
a, World m
w {entities = es}, Access m ()
hook)
despawn :: EntityID -> World m -> (IntMap Dynamic, World m)
despawn :: forall (m :: * -> *).
EntityID -> World m -> (IntMap Dynamic, World m)
despawn EntityID
e World m
w = let (IntMap Dynamic
a, Entities m
es) = EntityID -> Entities m -> (IntMap Dynamic, Entities m)
forall (m :: * -> *).
EntityID -> Entities m -> (IntMap Dynamic, Entities m)
E.despawn EntityID
e (World m -> Entities m
forall (m :: * -> *). World m -> Entities m
entities World m
w) in (IntMap Dynamic
a, World m
w {entities = es})