-- 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: -- -- 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