-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | A fast ECS for game engine programming
--
-- A fast ECS for game engine programming
@package apecs
@version 0.3.0.2
module Apecs.Core
-- | An Entity is really just an Int in a newtype, used to index into a
-- component store.
newtype Entity
Entity :: Int -> Entity
-- | A system is a newtype around `ReaderT w IO a`, where w is the
-- game world variable.
newtype System w a
System :: ReaderT w IO a -> System w a
[unSystem] :: System w a -> ReaderT w IO a
-- | A component is defined by the type of its storage The storage in turn
-- supplies runtime types for the component. For the component to be
-- valid, its Storage must be an instance of Store.
class (Elem (Storage c) ~ c, Store (Storage c)) => Component c where {
type family Storage c;
}
-- | A world Has a component if it can produce its Storage
class Component c => Has w c
getStore :: Has w c => System w (Storage c)
-- | Holds components indexed by entities
--
-- Laws:
--
--
-- - For all entities in exmplMembers s, explExists s
-- ety must be true.
-- - If for some entity explExists s ety, explGet s
-- ety should safely return a non-bottom value.
--
class Store s where {
type family Elem s;
}
-- | Initialize the store with its initialization arguments.
initStore :: Store s => IO s
-- | Writes a component
explSet :: Store s => s -> Int -> Elem s -> IO ()
-- | Reads a component from the store. What happens if the component does
-- not exist is left undefined.
explGet :: Store s => s -> Int -> IO (Elem s)
-- | Destroys the component for a given index.
explDestroy :: Store s => s -> Int -> IO ()
-- | Returns an unboxed vector of member indices
explMembers :: Store s => s -> IO (Vector Int)
-- | Returns whether there is a component for the given index
explExists :: Store s => s -> Int -> IO Bool
-- | Psuedocomponent indicating the absence of a.
data Not a
Not :: Not a
-- | Pseudostore used to produce values of type Not a
newtype NotStore s
NotStore :: s -> NotStore s
-- | Pseudostore used to produce values of type Maybe a
newtype MaybeStore s
MaybeStore :: s -> MaybeStore s
-- | Pseudostore used to produce values of type Either p q
data EitherStore sp sq
EitherStore :: sp -> sq -> EitherStore sp sq
data Filter c
Filter :: Filter c
newtype FilterStore s
FilterStore :: s -> FilterStore s
-- | Pseudostore used to produce components of type Entity
data EntityStore
EntityStore :: EntityStore
instance GHC.Show.Show (Apecs.Core.Filter c)
instance GHC.Classes.Eq (Apecs.Core.Filter c)
instance Apecs.Core.Component Apecs.Core.Entity
instance Apecs.Core.Has w Apecs.Core.Entity
instance Apecs.Core.Store Apecs.Core.EntityStore
instance Apecs.Core.Component c => Apecs.Core.Component (Apecs.Core.Filter c)
instance Apecs.Core.Has w c => Apecs.Core.Has w (Apecs.Core.Filter c)
instance Apecs.Core.Store s => Apecs.Core.Store (Apecs.Core.FilterStore s)
instance (Apecs.Core.Component p, Apecs.Core.Component q) => Apecs.Core.Component (Data.Either.Either p q)
instance (Apecs.Core.Has w p, Apecs.Core.Has w q) => Apecs.Core.Has w (Data.Either.Either p q)
instance (Apecs.Core.Store sp, Apecs.Core.Store sq) => Apecs.Core.Store (Apecs.Core.EitherStore sp sq)
instance Apecs.Core.Component c => Apecs.Core.Component (GHC.Base.Maybe c)
instance Apecs.Core.Has w c => Apecs.Core.Has w (GHC.Base.Maybe c)
instance Apecs.Core.Store s => Apecs.Core.Store (Apecs.Core.MaybeStore s)
instance Apecs.Core.Component c => Apecs.Core.Component (Apecs.Core.Not c)
instance Apecs.Core.Has w c => Apecs.Core.Has w (Apecs.Core.Not c)
instance Apecs.Core.Store s => Apecs.Core.Store (Apecs.Core.NotStore s)
instance (Apecs.Core.Component t_0, Apecs.Core.Component t_1) => Apecs.Core.Component (t_0, t_1)
instance (Apecs.Core.Has w t_0, Apecs.Core.Has w t_1) => Apecs.Core.Has w (t_0, t_1)
instance (Apecs.Core.Store t_0, Apecs.Core.Store t_1) => Apecs.Core.Store (t_0, t_1)
instance (Apecs.Core.Component t_0, Apecs.Core.Component t_1, Apecs.Core.Component t_2) => Apecs.Core.Component (t_0, t_1, t_2)
instance (Apecs.Core.Has w t_0, Apecs.Core.Has w t_1, Apecs.Core.Has w t_2) => Apecs.Core.Has w (t_0, t_1, t_2)
instance (Apecs.Core.Store t_0, Apecs.Core.Store t_1, Apecs.Core.Store t_2) => Apecs.Core.Store (t_0, t_1, t_2)
instance (Apecs.Core.Component t_0, Apecs.Core.Component t_1, Apecs.Core.Component t_2, Apecs.Core.Component t_3) => Apecs.Core.Component (t_0, t_1, t_2, t_3)
instance (Apecs.Core.Has w t_0, Apecs.Core.Has w t_1, Apecs.Core.Has w t_2, Apecs.Core.Has w t_3) => Apecs.Core.Has w (t_0, t_1, t_2, t_3)
instance (Apecs.Core.Store t_0, Apecs.Core.Store t_1, Apecs.Core.Store t_2, Apecs.Core.Store t_3) => Apecs.Core.Store (t_0, t_1, t_2, t_3)
instance (Apecs.Core.Component t_0, Apecs.Core.Component t_1, Apecs.Core.Component t_2, Apecs.Core.Component t_3, Apecs.Core.Component t_4) => Apecs.Core.Component (t_0, t_1, t_2, t_3, t_4)
instance (Apecs.Core.Has w t_0, Apecs.Core.Has w t_1, Apecs.Core.Has w t_2, Apecs.Core.Has w t_3, Apecs.Core.Has w t_4) => Apecs.Core.Has w (t_0, t_1, t_2, t_3, t_4)
instance (Apecs.Core.Store t_0, Apecs.Core.Store t_1, Apecs.Core.Store t_2, Apecs.Core.Store t_3, Apecs.Core.Store t_4) => Apecs.Core.Store (t_0, t_1, t_2, t_3, t_4)
instance (Apecs.Core.Component t_0, Apecs.Core.Component t_1, Apecs.Core.Component t_2, Apecs.Core.Component t_3, Apecs.Core.Component t_4, Apecs.Core.Component t_5) => Apecs.Core.Component (t_0, t_1, t_2, t_3, t_4, t_5)
instance (Apecs.Core.Has w t_0, Apecs.Core.Has w t_1, Apecs.Core.Has w t_2, Apecs.Core.Has w t_3, Apecs.Core.Has w t_4, Apecs.Core.Has w t_5) => Apecs.Core.Has w (t_0, t_1, t_2, t_3, t_4, t_5)
instance (Apecs.Core.Store t_0, Apecs.Core.Store t_1, Apecs.Core.Store t_2, Apecs.Core.Store t_3, Apecs.Core.Store t_4, Apecs.Core.Store t_5) => Apecs.Core.Store (t_0, t_1, t_2, t_3, t_4, t_5)
instance (Apecs.Core.Component t_0, Apecs.Core.Component t_1, Apecs.Core.Component t_2, Apecs.Core.Component t_3, Apecs.Core.Component t_4, Apecs.Core.Component t_5, Apecs.Core.Component t_6) => Apecs.Core.Component (t_0, t_1, t_2, t_3, t_4, t_5, t_6)
instance (Apecs.Core.Has w t_0, Apecs.Core.Has w t_1, Apecs.Core.Has w t_2, Apecs.Core.Has w t_3, Apecs.Core.Has w t_4, Apecs.Core.Has w t_5, Apecs.Core.Has w t_6) => Apecs.Core.Has w (t_0, t_1, t_2, t_3, t_4, t_5, t_6)
instance (Apecs.Core.Store t_0, Apecs.Core.Store t_1, Apecs.Core.Store t_2, Apecs.Core.Store t_3, Apecs.Core.Store t_4, Apecs.Core.Store t_5, Apecs.Core.Store t_6) => Apecs.Core.Store (t_0, t_1, t_2, t_3, t_4, t_5, t_6)
instance (Apecs.Core.Component t_0, Apecs.Core.Component t_1, Apecs.Core.Component t_2, Apecs.Core.Component t_3, Apecs.Core.Component t_4, Apecs.Core.Component t_5, Apecs.Core.Component t_6, Apecs.Core.Component t_7) => Apecs.Core.Component (t_0, t_1, t_2, t_3, t_4, t_5, t_6, t_7)
instance (Apecs.Core.Has w t_0, Apecs.Core.Has w t_1, Apecs.Core.Has w t_2, Apecs.Core.Has w t_3, Apecs.Core.Has w t_4, Apecs.Core.Has w t_5, Apecs.Core.Has w t_6, Apecs.Core.Has w t_7) => Apecs.Core.Has w (t_0, t_1, t_2, t_3, t_4, t_5, t_6, t_7)
instance (Apecs.Core.Store t_0, Apecs.Core.Store t_1, Apecs.Core.Store t_2, Apecs.Core.Store t_3, Apecs.Core.Store t_4, Apecs.Core.Store t_5, Apecs.Core.Store t_6, Apecs.Core.Store t_7) => Apecs.Core.Store (t_0, t_1, t_2, t_3, t_4, t_5, t_6, t_7)
instance Control.Monad.IO.Class.MonadIO (Apecs.Core.System w)
instance GHC.Base.Applicative (Apecs.Core.System w)
instance GHC.Base.Monad (Apecs.Core.System w)
instance GHC.Base.Functor (Apecs.Core.System w)
instance GHC.Show.Show Apecs.Core.Entity
instance GHC.Classes.Ord Apecs.Core.Entity
instance GHC.Classes.Eq Apecs.Core.Entity
instance Apecs.Core.Has w c => Apecs.Core.Has w (Data.Functor.Identity.Identity c)
instance Apecs.Core.Component c => Apecs.Core.Component (Data.Functor.Identity.Identity c)
instance Apecs.Core.Store s => Apecs.Core.Store (Data.Functor.Identity.Identity s)
module Apecs.System
-- | Run a system with a game world
runSystem :: System w a -> w -> IO a
-- | Run a system with a game world
runWith :: w -> System w a -> IO a
get :: forall w c. Has w c => Entity -> System w c
-- | Writes a component to a given entity. Will overwrite existing
-- components. The type was originally 'Entity c -> c -> System w
-- ()', but is relaxed to 'Entity e' so you don't always have to write
-- 'set . cast'
set :: forall w c. Has w c => Entity -> c -> System w ()
-- | Returns whether the given entity has component c Note that
-- c is a phantom argument, used only to convey the type of the
-- entity to be queried.
exists :: forall w c. Has w c => Entity -> c -> System w Bool
-- | Maps a function over all entities with a cx, and writes their
-- cy
cmap :: forall world cx cy. (Has world cx, Has world cy) => (cx -> cy) -> System world ()
-- | Monadically iterates over all entites with a cx
cmapM :: forall world c a. Has world c => (c -> System world a) -> System world [a]
-- | Monadically iterates over all entites with a cx
cmapM_ :: forall world c a. Has world c => (c -> System world a) -> System world ()
-- | Get all components c. Call as [(c,Entity)] to read
-- the entity/index.
getAll :: forall world c. Has world c => System world [c]
-- | Destroys component c for the given entity. Note that
-- c is a phantom argument, used only to convey the type of the
-- entity to be destroyed.
destroy :: forall w c. Has w c => Entity -> c -> System w ()
-- | Applies a function, if possible.
modify :: forall w c. Has w c => Entity -> (c -> c) -> System w ()
-- | Counts the number of entities with a c
count :: forall w c. Has w c => c -> System w Int
module Apecs.Stores
-- | A map based on Data.Intmap.Strict. O(log(n)) for most
-- operations.
data Map c
-- | A cache around another store. Note that iterating over a cache is
-- linear in cache size, so sparsely populated caches might actually
-- decrease performance.
data Cache (n :: Nat) s
-- | A Unique contains zero or one component. Writing to it overwrites both
-- the previous component and its owner. Its main purpose is to be a
-- Map optimized for when only ever one component inhabits it.
data Unique c
-- | A Global contains exactly one component. Initialized with
-- mempty The store will return true for every existence check,
-- but only ever gives (-1) as its inhabitant. The entity argument is
-- ignored when setting/getting a global.
data Global c
-- | An empty type class indicating that the store behaves like a regular
-- map, and can therefore safely be cached.
class Store s => Cachable s
instance Apecs.Stores.Cachable (Apecs.Stores.Map s)
instance (GHC.TypeNats.KnownNat n, Apecs.Stores.Cachable s) => Apecs.Stores.Cachable (Apecs.Stores.Cache n s)
instance (GHC.TypeNats.KnownNat n, Apecs.Stores.Cachable s) => Apecs.Core.Store (Apecs.Stores.Cache n s)
instance GHC.Base.Monoid c => Apecs.Core.Store (Apecs.Stores.Global c)
instance Apecs.Core.Store (Apecs.Stores.Unique c)
instance Apecs.Core.Store (Apecs.Stores.Map c)
module Apecs.Concurrent
-- | Executes a list of systems concurrently, and blocks until all have
-- finished. Provides zero protection against race conditions and other
-- hazards, so use with caution.
concurrently :: [System w ()] -> System w ()
-- | Parallel version of cmap.
pmap :: forall w x y. (Has w y, Has w x) => Int -> (x -> y) -> System w ()
module Apecs.Util
-- | Explicitly invoke the garbage collector
runGC :: System w ()
-- | Convenience entity (-1), used in places where the exact entity value
-- does not matter, i.e. a global store.
global :: Entity
-- | Convenience proxy value
proxy :: forall t. t
-- | Component used by newEntity to track the number of issued entities.
-- Automatically added to any world created with makeWorld
data EntityCounter
-- | Bumps the EntityCounter and yields its value
nextEntity :: Has w EntityCounter => System w Entity
-- | Writes the given components to a new entity, and yields that entity.
-- The return value is often ignored.
newEntity :: (Store (Storage c), Has w c, Has w EntityCounter) => c -> System w Entity
-- | Quantize turns a world-space coordinate into a table-space coordinate
-- by dividing by the given cell size and rounding towards negative
-- infinity.
quantize :: (Fractional (v a), Integral b, RealFrac a, Functor v) => v a -> v a -> v b
-- | Turns a table-space vector into an integral index, given some table
-- size vector. Yields Nothing for out-of-bounds queries
flatten :: (Applicative v, Integral a, Foldable v) => v a -> v a -> Maybe a
-- | Tests whether a vector is in the region given by 0 and the size vector
-- (inclusive)
inbounds :: (Num a, Ord a, Applicative v, Foldable v) => v a -> v a -> Bool
-- | For two table-space vectors indicating a region's bounds, gives a list
-- of the vectors contained between them. This is useful for querying a
-- spatial hash.
region :: (Enum a, Applicative v, Traversable v) => v a -> v a -> [v a]
-- | flatten, but yields garbage for out-of-bounds vectors.
flatten' :: (Applicative v, Integral a, Foldable v) => v a -> v a -> a
-- | Runs a system and gives its execution time in seconds
timeSystem :: System w a -> System w (Double, a)
-- | Runs a system, discards its output, and gives its execution time in
-- seconds
timeSystem_ :: System w a -> System w Double
instance GHC.Show.Show Apecs.Util.EntityCounter
instance GHC.Classes.Eq Apecs.Util.EntityCounter
instance GHC.Base.Monoid Apecs.Util.EntityCounter
instance Apecs.Core.Component Apecs.Util.EntityCounter
module Apecs.TH
-- |
-- makeWorld "WorldName" [''Component1, ''Component2, ...]
--
--
-- turns into
--
--
-- data WorldName = WorldName Component1 Component2 ... EntityCounter
-- instance WorldName `Has` Component1 where ...
-- instance WorldName `Has` Component2 where ...
-- ...
-- instance WorldName `Has` EntityCounter where ...
--
-- initWorldName :: IO WorldName
-- initWorldName = WorldName <$> initStore <*> initStore <*> ... <*> initStore
--
--
-- |
makeWorld :: String -> [Name] -> Q [Dec]
-- | Same as makeWorld, but has no EntityCounter
makeWorldNoEC :: String -> [Name] -> Q [Dec]
-- | This module forms the apecs Prelude. It selectively re-exports the
-- user-facing functions from the submodules.
module Apecs
-- | A system is a newtype around `ReaderT w IO a`, where w is the
-- game world variable.
newtype System w a
System :: ReaderT w IO a -> System w a
[unSystem] :: System w a -> ReaderT w IO a
-- | A component is defined by the type of its storage The storage in turn
-- supplies runtime types for the component. For the component to be
-- valid, its Storage must be an instance of Store.
class (Elem (Storage c) ~ c, Store (Storage c)) => Component c where {
type family Storage c;
}
-- | An Entity is really just an Int in a newtype, used to index into a
-- component store.
newtype Entity
Entity :: Int -> Entity
-- | A world Has a component if it can produce its Storage
class Component c => Has w c
getStore :: Has w c => System w (Storage c)
-- | Psuedocomponent indicating the absence of a.
data Not a
Not :: Not a
-- | A map based on Data.Intmap.Strict. O(log(n)) for most
-- operations.
data Map c
-- | A Unique contains zero or one component. Writing to it overwrites both
-- the previous component and its owner. Its main purpose is to be a
-- Map optimized for when only ever one component inhabits it.
data Unique c
-- | A Global contains exactly one component. Initialized with
-- mempty The store will return true for every existence check,
-- but only ever gives (-1) as its inhabitant. The entity argument is
-- ignored when setting/getting a global.
data Global c
-- | A cache around another store. Note that iterating over a cache is
-- linear in cache size, so sparsely populated caches might actually
-- decrease performance.
data Cache (n :: Nat) s
-- | Initialize the store with its initialization arguments.
initStore :: Store s => IO s
get :: forall w c. Has w c => Entity -> System w c
-- | Writes a component to a given entity. Will overwrite existing
-- components. The type was originally 'Entity c -> c -> System w
-- ()', but is relaxed to 'Entity e' so you don't always have to write
-- 'set . cast'
set :: forall w c. Has w c => Entity -> c -> System w ()
-- | Get all components c. Call as [(c,Entity)] to read
-- the entity/index.
getAll :: forall world c. Has world c => System world [c]
-- | Maps a function over all entities with a cx, and writes their
-- cy
cmap :: forall world cx cy. (Has world cx, Has world cy) => (cx -> cy) -> System world ()
-- | Monadically iterates over all entites with a cx
cmapM :: forall world c a. Has world c => (c -> System world a) -> System world [a]
-- | Monadically iterates over all entites with a cx
cmapM_ :: forall world c a. Has world c => (c -> System world a) -> System world ()
-- | Applies a function, if possible.
modify :: forall w c. Has w c => Entity -> (c -> c) -> System w ()
-- | Destroys component c for the given entity. Note that
-- c is a phantom argument, used only to convey the type of the
-- entity to be destroyed.
destroy :: forall w c. Has w c => Entity -> c -> System w ()
-- | Returns whether the given entity has component c Note that
-- c is a phantom argument, used only to convey the type of the
-- entity to be queried.
exists :: forall w c. Has w c => Entity -> c -> System w Bool
-- | Run a system with a game world
runSystem :: System w a -> w -> IO a
-- | Run a system with a game world
runWith :: w -> System w a -> IO a
-- | Explicitly invoke the garbage collector
runGC :: System w ()
-- | Component used by newEntity to track the number of issued entities.
-- Automatically added to any world created with makeWorld
data EntityCounter
-- | Writes the given components to a new entity, and yields that entity.
-- The return value is often ignored.
newEntity :: (Store (Storage c), Has w c, Has w EntityCounter) => c -> System w Entity
-- | Convenience entity (-1), used in places where the exact entity value
-- does not matter, i.e. a global store.
global :: Entity
-- | Convenience proxy value
proxy :: forall t. t
-- |
-- makeWorld "WorldName" [''Component1, ''Component2, ...]
--
--
-- turns into
--
--
-- data WorldName = WorldName Component1 Component2 ... EntityCounter
-- instance WorldName `Has` Component1 where ...
-- instance WorldName `Has` Component2 where ...
-- ...
-- instance WorldName `Has` EntityCounter where ...
--
-- initWorldName :: IO WorldName
-- initWorldName = WorldName <$> initStore <*> initStore <*> ... <*> initStore
--
--
-- |
makeWorld :: String -> [Name] -> Q [Dec]
-- | Retrieves a function of the current environment.
asks :: MonadReader r m => (r -> a) -> m a
-- | Retrieves the monad environment.
ask :: MonadReader r m => m r
-- | Lift a computation from the IO monad.
liftIO :: MonadIO m => forall a. () => IO a -> m a
-- | Lift a computation from the argument monad to the constructed monad.
lift :: MonadTrans t => forall (m :: * -> *) a. Monad m => m a -> t m a