-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Fast ECS framework for game programming
--   
--   Apecs is an Entity Component System framework, suitable for
--   high-performance game programming.
@package apecs
@version 0.4.1.1

module Apecs.Core

-- | An Entity is just an integer, used to index into a component store. In
--   general, use <tt>newEntity</tt>, <tt>cmap</tt>, and component tags
--   instead of manipulating these directly.
--   
--   For performance reasons, negative values like (-1) are reserved for
--   stores to represent special values, so avoid using these.
newtype Entity
Entity :: Int -> Entity
[unEntity] :: Entity -> Int

-- | A System is a newtype around `ReaderT w IO a`, where <tt>w</tt> is the
--   game world variable. Systems mainly serve to
--   
--   <ul>
--   <li>Lift side effects into the IO Monad.</li>
--   <li>Allow type-based lookup of a component's store through
--   <tt>getStore</tt>.</li>
--   </ul>
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 specifying how it is stored. The constraint
--   ensures that stores and components are mapped one-to-one.
class (Elem (Storage c) ~ c) => Component c where {
    type family Storage c;
}

-- | <tt>Has w c</tt> means that world <tt>w</tt> can produce a <tt>Storage
--   c</tt>.
class Component c => Has w c
getStore :: Has w c => System w (Storage c)

-- | The type of components stored by a store, e.g. <tt>Elem (Map c) =
--   c</tt>.

-- | Indicates that the store <tt>s</tt> can be initialized. Generally,
--   "base" stores like <tt>Map c</tt> can be initialized, but composite
--   stores like <tt>MaybeStore s</tt> cannot.
class ExplInit s

-- | Initialize a new empty store.
explInit :: ExplInit s => IO s

-- | Stores that we can read using <tt>explGet</tt> and
--   <tt>explExists</tt>. For some entity <tt>e</tt>, <tt>eplGet s e</tt>
--   is only guaranteed to be safe if <tt>explExists s e</tt> returns
--   <tt>True</tt>.
class ExplGet s

-- | Reads a component from the store. What happens if the component does
--   not exist is left undefined, and might not necessarily crash.
explGet :: ExplGet s => s -> Int -> IO (Elem s)

-- | Returns whether there is a component for the given index.
explExists :: ExplGet s => s -> Int -> IO Bool

-- | Stores that can be written.
class ExplSet s

-- | Writes a component to the store.
explSet :: ExplSet s => s -> Int -> Elem s -> IO ()

-- | Stores that components can be removed from.
class ExplDestroy s

-- | Destroys the component for a given index.
explDestroy :: ExplDestroy s => s -> Int -> IO ()

-- | Stores that we can request a list of member entities for.
class ExplMembers s

-- | Returns an unboxed vector of member indices
explMembers :: ExplMembers s => s -> IO (Vector Int)
type Get w c = (Has w c, ExplGet (Storage c))
type Set w c = (Has w c, ExplSet (Storage c))
type Members w c = (Has w c, ExplMembers (Storage c))
type Destroy w c = (Has w c, ExplDestroy (Storage c))

-- | Psuedocomponent indicating the absence of <tt>a</tt>. Mainly used as
--   e.g. <tt>cmap $ (a, Not b) -&gt; c</tt> to iterate over entities with
--   an <tt>a</tt> but no <tt>b</tt>. Can also be used to delete
--   components, like <tt>cmap $ a -&gt; (Not :: Not a)</tt> to delete
--   every <tt>a</tt> component.
data Not a
Not :: Not a

-- | Pseudostore used to produce values of type <tt>Not a</tt>, inverts
--   <tt>explExists</tt>, and destroys instead of <tt>explSet</tt>.
newtype NotStore s
NotStore :: s -> NotStore s

-- | Pseudostore used to produce values of type <tt>Maybe a</tt>. Will
--   always return <tt>True</tt> for <tt>explExists</tt>. Writing can both
--   set and delete a component using <tt>Just</tt> and <tt>Nothing</tt>
--   respectively.
newtype MaybeStore s
MaybeStore :: s -> MaybeStore s

-- | Used for <a>Either</a>, a logical disjunction between two components.
--   As expected, Either is used to model error values. Getting an
--   <tt>Either a b</tt> will first attempt to get a <tt>b</tt> and return
--   it as <tt>Right b</tt>, or if it does not exist, get an <tt>a</tt> as
--   <tt>Left a</tt>. Can also be used to set one of two things.
data EitherStore sa sb
EitherStore :: sa -> sb -> EitherStore sa sb

-- | Pseudocomponent that functions normally for <tt>explExists</tt> and
--   <tt>explMembers</tt>, but always return <tt>Filter</tt> for
--   <tt>explGet</tt>. Can be used in cmap as <tt>cmap $ (Filter :: Filter
--   a) -&gt; b</tt>. Since the above can be written more consicely as
--   <tt>cmap $ (_ :: a) -&gt; b</tt>, it is rarely directly. More
--   interestingly, we can define reusable filters like <tt>movables =
--   Filter :: Filter (Position, Velocity)</tt>.
data Filter c
Filter :: Filter c
newtype FilterStore s
FilterStore :: s -> FilterStore s

-- | Pseudostore used to produce components of type <a>Entity</a>. Always
--   returns <tt>True</tt> for <tt>explExists</tt>, and echoes back the
--   entity argument for <tt>explGet</tt>. Used in e.g. <tt>cmap $ (a, ety
--   :: Entity) -&gt; b</tt> to access the current 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.ExplGet 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.ExplGet s => Apecs.Core.ExplGet (Apecs.Core.FilterStore s)
instance Apecs.Core.ExplMembers s => Apecs.Core.ExplMembers (Apecs.Core.FilterStore s)
instance (Apecs.Core.Component ca, Apecs.Core.Component cb) => Apecs.Core.Component (Data.Either.Either ca cb)
instance (Apecs.Core.Has w ca, Apecs.Core.Has w cb) => Apecs.Core.Has w (Data.Either.Either ca cb)
instance (Apecs.Core.ExplGet sa, Apecs.Core.ExplGet sb) => Apecs.Core.ExplGet (Apecs.Core.EitherStore sa sb)
instance (Apecs.Core.ExplSet sa, Apecs.Core.ExplSet sb) => Apecs.Core.ExplSet (Apecs.Core.EitherStore sa sb)
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.ExplGet s => Apecs.Core.ExplGet (Apecs.Core.MaybeStore s)
instance (Apecs.Core.ExplDestroy s, Apecs.Core.ExplSet s) => Apecs.Core.ExplSet (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.ExplGet s => Apecs.Core.ExplGet (Apecs.Core.NotStore s)
instance Apecs.Core.ExplDestroy s => Apecs.Core.ExplSet (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.ExplGet t_0, Apecs.Core.ExplGet t_1) => Apecs.Core.ExplGet (t_0, t_1)
instance (Apecs.Core.ExplSet t_0, Apecs.Core.ExplSet t_1) => Apecs.Core.ExplSet (t_0, t_1)
instance (Apecs.Core.ExplDestroy t_0, Apecs.Core.ExplDestroy t_1) => Apecs.Core.ExplDestroy (t_0, t_1)
instance (Apecs.Core.ExplMembers t_0, Apecs.Core.ExplGet t_1) => Apecs.Core.ExplMembers (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.ExplGet t_0, Apecs.Core.ExplGet t_1, Apecs.Core.ExplGet t_2) => Apecs.Core.ExplGet (t_0, t_1, t_2)
instance (Apecs.Core.ExplSet t_0, Apecs.Core.ExplSet t_1, Apecs.Core.ExplSet t_2) => Apecs.Core.ExplSet (t_0, t_1, t_2)
instance (Apecs.Core.ExplDestroy t_0, Apecs.Core.ExplDestroy t_1, Apecs.Core.ExplDestroy t_2) => Apecs.Core.ExplDestroy (t_0, t_1, t_2)
instance (Apecs.Core.ExplMembers t_0, Apecs.Core.ExplGet t_1, Apecs.Core.ExplGet t_2) => Apecs.Core.ExplMembers (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.ExplGet t_0, Apecs.Core.ExplGet t_1, Apecs.Core.ExplGet t_2, Apecs.Core.ExplGet t_3) => Apecs.Core.ExplGet (t_0, t_1, t_2, t_3)
instance (Apecs.Core.ExplSet t_0, Apecs.Core.ExplSet t_1, Apecs.Core.ExplSet t_2, Apecs.Core.ExplSet t_3) => Apecs.Core.ExplSet (t_0, t_1, t_2, t_3)
instance (Apecs.Core.ExplDestroy t_0, Apecs.Core.ExplDestroy t_1, Apecs.Core.ExplDestroy t_2, Apecs.Core.ExplDestroy t_3) => Apecs.Core.ExplDestroy (t_0, t_1, t_2, t_3)
instance (Apecs.Core.ExplMembers t_0, Apecs.Core.ExplGet t_1, Apecs.Core.ExplGet t_2, Apecs.Core.ExplGet t_3) => Apecs.Core.ExplMembers (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.ExplGet t_0, Apecs.Core.ExplGet t_1, Apecs.Core.ExplGet t_2, Apecs.Core.ExplGet t_3, Apecs.Core.ExplGet t_4) => Apecs.Core.ExplGet (t_0, t_1, t_2, t_3, t_4)
instance (Apecs.Core.ExplSet t_0, Apecs.Core.ExplSet t_1, Apecs.Core.ExplSet t_2, Apecs.Core.ExplSet t_3, Apecs.Core.ExplSet t_4) => Apecs.Core.ExplSet (t_0, t_1, t_2, t_3, t_4)
instance (Apecs.Core.ExplDestroy t_0, Apecs.Core.ExplDestroy t_1, Apecs.Core.ExplDestroy t_2, Apecs.Core.ExplDestroy t_3, Apecs.Core.ExplDestroy t_4) => Apecs.Core.ExplDestroy (t_0, t_1, t_2, t_3, t_4)
instance (Apecs.Core.ExplMembers t_0, Apecs.Core.ExplGet t_1, Apecs.Core.ExplGet t_2, Apecs.Core.ExplGet t_3, Apecs.Core.ExplGet t_4) => Apecs.Core.ExplMembers (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.ExplGet t_0, Apecs.Core.ExplGet t_1, Apecs.Core.ExplGet t_2, Apecs.Core.ExplGet t_3, Apecs.Core.ExplGet t_4, Apecs.Core.ExplGet t_5) => Apecs.Core.ExplGet (t_0, t_1, t_2, t_3, t_4, t_5)
instance (Apecs.Core.ExplSet t_0, Apecs.Core.ExplSet t_1, Apecs.Core.ExplSet t_2, Apecs.Core.ExplSet t_3, Apecs.Core.ExplSet t_4, Apecs.Core.ExplSet t_5) => Apecs.Core.ExplSet (t_0, t_1, t_2, t_3, t_4, t_5)
instance (Apecs.Core.ExplDestroy t_0, Apecs.Core.ExplDestroy t_1, Apecs.Core.ExplDestroy t_2, Apecs.Core.ExplDestroy t_3, Apecs.Core.ExplDestroy t_4, Apecs.Core.ExplDestroy t_5) => Apecs.Core.ExplDestroy (t_0, t_1, t_2, t_3, t_4, t_5)
instance (Apecs.Core.ExplMembers t_0, Apecs.Core.ExplGet t_1, Apecs.Core.ExplGet t_2, Apecs.Core.ExplGet t_3, Apecs.Core.ExplGet t_4, Apecs.Core.ExplGet t_5) => Apecs.Core.ExplMembers (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.ExplGet t_0, Apecs.Core.ExplGet t_1, Apecs.Core.ExplGet t_2, Apecs.Core.ExplGet t_3, Apecs.Core.ExplGet t_4, Apecs.Core.ExplGet t_5, Apecs.Core.ExplGet t_6) => Apecs.Core.ExplGet (t_0, t_1, t_2, t_3, t_4, t_5, t_6)
instance (Apecs.Core.ExplSet t_0, Apecs.Core.ExplSet t_1, Apecs.Core.ExplSet t_2, Apecs.Core.ExplSet t_3, Apecs.Core.ExplSet t_4, Apecs.Core.ExplSet t_5, Apecs.Core.ExplSet t_6) => Apecs.Core.ExplSet (t_0, t_1, t_2, t_3, t_4, t_5, t_6)
instance (Apecs.Core.ExplDestroy t_0, Apecs.Core.ExplDestroy t_1, Apecs.Core.ExplDestroy t_2, Apecs.Core.ExplDestroy t_3, Apecs.Core.ExplDestroy t_4, Apecs.Core.ExplDestroy t_5, Apecs.Core.ExplDestroy t_6) => Apecs.Core.ExplDestroy (t_0, t_1, t_2, t_3, t_4, t_5, t_6)
instance (Apecs.Core.ExplMembers t_0, Apecs.Core.ExplGet t_1, Apecs.Core.ExplGet t_2, Apecs.Core.ExplGet t_3, Apecs.Core.ExplGet t_4, Apecs.Core.ExplGet t_5, Apecs.Core.ExplGet t_6) => Apecs.Core.ExplMembers (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.ExplGet t_0, Apecs.Core.ExplGet t_1, Apecs.Core.ExplGet t_2, Apecs.Core.ExplGet t_3, Apecs.Core.ExplGet t_4, Apecs.Core.ExplGet t_5, Apecs.Core.ExplGet t_6, Apecs.Core.ExplGet t_7) => Apecs.Core.ExplGet (t_0, t_1, t_2, t_3, t_4, t_5, t_6, t_7)
instance (Apecs.Core.ExplSet t_0, Apecs.Core.ExplSet t_1, Apecs.Core.ExplSet t_2, Apecs.Core.ExplSet t_3, Apecs.Core.ExplSet t_4, Apecs.Core.ExplSet t_5, Apecs.Core.ExplSet t_6, Apecs.Core.ExplSet t_7) => Apecs.Core.ExplSet (t_0, t_1, t_2, t_3, t_4, t_5, t_6, t_7)
instance (Apecs.Core.ExplDestroy t_0, Apecs.Core.ExplDestroy t_1, Apecs.Core.ExplDestroy t_2, Apecs.Core.ExplDestroy t_3, Apecs.Core.ExplDestroy t_4, Apecs.Core.ExplDestroy t_5, Apecs.Core.ExplDestroy t_6, Apecs.Core.ExplDestroy t_7) => Apecs.Core.ExplDestroy (t_0, t_1, t_2, t_3, t_4, t_5, t_6, t_7)
instance (Apecs.Core.ExplMembers t_0, Apecs.Core.ExplGet t_1, Apecs.Core.ExplGet t_2, Apecs.Core.ExplGet t_3, Apecs.Core.ExplGet t_4, Apecs.Core.ExplGet t_5, Apecs.Core.ExplGet t_6, Apecs.Core.ExplGet t_7) => Apecs.Core.ExplMembers (t_0, t_1, t_2, t_3, t_4, t_5, t_6, t_7)
instance Apecs.Core.Has w ()
instance Apecs.Core.Component ()
instance Apecs.Core.ExplGet ()
instance Apecs.Core.ExplSet ()
instance Apecs.Core.ExplDestroy ()
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 GHC.Num.Num Apecs.Core.Entity
instance Apecs.Core.ExplMembers s => Apecs.Core.ExplMembers (Data.Functor.Identity.Identity s)
instance Apecs.Core.ExplDestroy s => Apecs.Core.ExplDestroy (Data.Functor.Identity.Identity s)
instance Apecs.Core.ExplSet s => Apecs.Core.ExplSet (Data.Functor.Identity.Identity s)
instance Apecs.Core.ExplGet s => Apecs.Core.ExplGet (Data.Functor.Identity.Identity s)
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)

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. Get w c => Entity -> System w c

-- | Writes a component to a given entity. Will overwrite existing
--   components. The type was originally 'Entity c -&gt; c -&gt; System w
--   ()', but is relaxed to 'Entity e' so you don't always have to write
--   'set . cast'
set :: forall w c. Set w c => Entity -> c -> System w ()

-- | Returns whether the given entity has component <tt>c</tt> Note that
--   <tt>c</tt> is a phantom argument, used only to convey the type of the
--   entity to be queried.
exists :: forall w c. Get w c => Entity -> Proxy c -> System w Bool

-- | Maps a function over all entities with a <tt>cx</tt>, and writes their
--   <tt>cy</tt>.
cmap :: forall w cx cy. (Get w cx, Members w cx, Set w cy) => (cx -> cy) -> System w ()

-- | Monadically iterates over all entites with a <tt>cx</tt>, and writes
--   their <tt>cy</tt>.
cmapM :: forall w cx cy. (Get w cx, Set w cy, Members w cx) => (cx -> System w cy) -> System w ()

-- | Monadically iterates over all entites with a <tt>cx</tt>
cmapM_ :: forall w c a. (Get w c, Members w c) => (c -> System w a) -> System w ()

-- | Fold over the game world; for example, <tt>cfold max (minBound ::
--   Foo)</tt> will find the maximum value of <tt>Foo</tt>. Strict in the
--   accumulator.
cfold :: forall w c a. (Members w c, Get w c) => (a -> c -> a) -> a -> System w a

-- | Monadically fold over the game world. Strict in the accumulator.
cfoldM :: forall w c a. (Members w c, Get w c) => (a -> c -> System w a) -> a -> System w a

-- | Monadically fold over the game world. Strict in the accumulator.
cfoldM_ :: forall w c a. (Members w c, Get w c) => (a -> c -> System w a) -> a -> System w ()

-- | Get all components <tt>c</tt>. Call as <tt>[(c,Entity)]</tt> to also
--   read the entity index.
getAll :: forall w c. (Get w c, Members w c) => System w [c]

-- | Destroys component <tt>c</tt> for the given entity. Note that
--   <tt>c</tt> is a phantom argument, used only to convey the type of the
--   entity to be destroyed.
destroy :: forall w c. Destroy w c => Entity -> Proxy c -> System w ()

-- | Applies a function, if possible.
modify :: forall w c. (Get w c, Set w c) => Entity -> (c -> c) -> System w ()

-- | Counts the number of entities with a <tt>c</tt>
count :: forall w c. Members w c => c -> System w Int

module Apecs.Stores

-- | A map based on <tt>Data.Intmap.Strict</tt>. O(log(n)) for most
--   operations.
data Map c

-- | A cache around another store. Caches store their members in a
--   fixed-size vector, so operations run in O(1). Caches can provide huge
--   performance boosts, especially for large numbers of components. The
--   cache size is given as a type-level argument.
--   
--   Note that iterating over a cache is linear in cache size, so sparsely
--   populated caches might actually decrease performance. In general, the
--   exact size of the cache does not matter as long as it reasonably
--   approximates the number of components present.
--   
--   The cache uses entity (-1) to internally represent missing entities,
--   so be wary when manually manipulating entities.
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
--   <tt>Map</tt> optimized for when only ever one component inhabits it.
data Unique c

-- | A Global contains exactly one component. The initial value is
--   <a>mempty</a> from the component's <a>Monoid</a> instance. When
--   operating on a global, any entity arguments are ignored. For example,
--   we can get a global component with <tt>get 0</tt> or <tt>get 1</tt> or
--   even <tt>get undefined</tt>.
data Global c

-- | An empty type class indicating that the store behaves like a regular
--   map, and can therefore safely be cached. An example of a store that
--   cannot be cached is <a>Unique</a>.
class Cachable s
instance (GHC.TypeNats.KnownNat n, Apecs.Stores.Cachable s) => Apecs.Stores.Cachable (Apecs.Stores.Cache n s)
instance (Apecs.Core.ExplInit s, GHC.TypeNats.KnownNat n, Apecs.Stores.Cachable s) => Apecs.Core.ExplInit (Apecs.Stores.Cache n s)
instance Apecs.Core.ExplGet s => Apecs.Core.ExplGet (Apecs.Stores.Cache n s)
instance Apecs.Core.ExplSet s => Apecs.Core.ExplSet (Apecs.Stores.Cache n s)
instance Apecs.Core.ExplDestroy s => Apecs.Core.ExplDestroy (Apecs.Stores.Cache n s)
instance Apecs.Core.ExplMembers s => Apecs.Core.ExplMembers (Apecs.Stores.Cache n s)
instance Apecs.Stores.Cachable (Apecs.Stores.Map s)
instance GHC.Base.Monoid c => Apecs.Core.ExplInit (Apecs.Stores.Global c)
instance Apecs.Core.ExplGet (Apecs.Stores.Global c)
instance Apecs.Core.ExplSet (Apecs.Stores.Global c)
instance Apecs.Core.ExplInit (Apecs.Stores.Unique c)
instance Apecs.Core.ExplGet (Apecs.Stores.Unique c)
instance Apecs.Core.ExplSet (Apecs.Stores.Unique c)
instance Apecs.Core.ExplDestroy (Apecs.Stores.Unique c)
instance Apecs.Core.ExplMembers (Apecs.Stores.Unique c)
instance Apecs.Core.ExplInit (Apecs.Stores.Map c)
instance Apecs.Core.ExplGet (Apecs.Stores.Map c)
instance Apecs.Core.ExplSet (Apecs.Stores.Map c)
instance Apecs.Core.ExplDestroy (Apecs.Stores.Map c)
instance Apecs.Core.ExplMembers (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 <tt>cmap</tt>.
pmap :: forall w cx cy. (Get w cx, Members w cx, Set w cy) => Int -> (cx -> cy) -> System w ()

module Apecs.Util

-- | Explicitly invoke the garbage collector
runGC :: System w ()

-- | Convenience entity, for use in places where the entity value does not
--   matter, i.e. a global store. Its value is -2, to avoid potential
--   conflicts with caches, which reserve -1.
global :: Entity

-- | Component used by newEntity to track the number of issued entities.
--   Automatically added to any world created with <tt>makeWorld</tt>
newtype EntityCounter
EntityCounter :: Sum Int -> EntityCounter
[getCounter] :: EntityCounter -> Sum Int

-- | 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 :: (Set w c, Get w EntityCounter, Set 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 GHC.Base.Semigroup Apecs.Util.EntityCounter
instance Apecs.Core.Component Apecs.Util.EntityCounter

module Apecs.TH

-- | <pre>
--   makeWorld "WorldName" [''Component1, ''Component2, ...]
--   </pre>
--   
--   turns into
--   
--   <pre>
--   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 &lt;$&gt; initStore &lt;*&gt; initStore &lt;*&gt; ... &lt;*&gt; initStore
--   </pre>
--   
--   |
makeWorld :: String -> [Name] -> Q [Dec]

-- | Same as <a>makeWorld</a>, but has no <a>EntityCounter</a>
makeWorldNoEC :: String -> [Name] -> Q [Dec]

-- | Same as makeWorld, but also makes a component instance:
makeWorldAndComponents :: 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 <tt>w</tt> is the
--   game world variable. Systems mainly serve to
--   
--   <ul>
--   <li>Lift side effects into the IO Monad.</li>
--   <li>Allow type-based lookup of a component's store through
--   <tt>getStore</tt>.</li>
--   </ul>
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 specifying how it is stored. The constraint
--   ensures that stores and components are mapped one-to-one.
class (Elem (Storage c) ~ c) => Component c where {
    type family Storage c;
}

-- | An Entity is just an integer, used to index into a component store. In
--   general, use <tt>newEntity</tt>, <tt>cmap</tt>, and component tags
--   instead of manipulating these directly.
--   
--   For performance reasons, negative values like (-1) are reserved for
--   stores to represent special values, so avoid using these.
newtype Entity
Entity :: Int -> Entity
[unEntity] :: Entity -> Int

-- | <tt>Has w c</tt> means that world <tt>w</tt> can produce a <tt>Storage
--   c</tt>.
class Component c => Has w c
getStore :: Has w c => System w (Storage c)

-- | Psuedocomponent indicating the absence of <tt>a</tt>. Mainly used as
--   e.g. <tt>cmap $ (a, Not b) -&gt; c</tt> to iterate over entities with
--   an <tt>a</tt> but no <tt>b</tt>. Can also be used to delete
--   components, like <tt>cmap $ a -&gt; (Not :: Not a)</tt> to delete
--   every <tt>a</tt> component.
data Not a
Not :: Not a
type Get w c = (Has w c, ExplGet (Storage c))
type Set w c = (Has w c, ExplSet (Storage c))
type Destroy w c = (Has w c, ExplDestroy (Storage c))
type Members w c = (Has w c, ExplMembers (Storage c))

-- | A map based on <tt>Data.Intmap.Strict</tt>. 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
--   <tt>Map</tt> optimized for when only ever one component inhabits it.
data Unique c

-- | A Global contains exactly one component. The initial value is
--   <a>mempty</a> from the component's <a>Monoid</a> instance. When
--   operating on a global, any entity arguments are ignored. For example,
--   we can get a global component with <tt>get 0</tt> or <tt>get 1</tt> or
--   even <tt>get undefined</tt>.
data Global c

-- | A cache around another store. Caches store their members in a
--   fixed-size vector, so operations run in O(1). Caches can provide huge
--   performance boosts, especially for large numbers of components. The
--   cache size is given as a type-level argument.
--   
--   Note that iterating over a cache is linear in cache size, so sparsely
--   populated caches might actually decrease performance. In general, the
--   exact size of the cache does not matter as long as it reasonably
--   approximates the number of components present.
--   
--   The cache uses entity (-1) to internally represent missing entities,
--   so be wary when manually manipulating entities.
data Cache (n :: Nat) s

-- | Initialize a new empty store.
explInit :: ExplInit s => IO s
get :: forall w c. Get w c => Entity -> System w c

-- | Writes a component to a given entity. Will overwrite existing
--   components. The type was originally 'Entity c -&gt; c -&gt; System w
--   ()', but is relaxed to 'Entity e' so you don't always have to write
--   'set . cast'
set :: forall w c. Set w c => Entity -> c -> System w ()

-- | Get all components <tt>c</tt>. Call as <tt>[(c,Entity)]</tt> to also
--   read the entity index.
getAll :: forall w c. (Get w c, Members w c) => System w [c]

-- | Maps a function over all entities with a <tt>cx</tt>, and writes their
--   <tt>cy</tt>.
cmap :: forall w cx cy. (Get w cx, Members w cx, Set w cy) => (cx -> cy) -> System w ()

-- | Monadically iterates over all entites with a <tt>cx</tt>, and writes
--   their <tt>cy</tt>.
cmapM :: forall w cx cy. (Get w cx, Set w cy, Members w cx) => (cx -> System w cy) -> System w ()

-- | Monadically iterates over all entites with a <tt>cx</tt>
cmapM_ :: forall w c a. (Get w c, Members w c) => (c -> System w a) -> System w ()

-- | Fold over the game world; for example, <tt>cfold max (minBound ::
--   Foo)</tt> will find the maximum value of <tt>Foo</tt>. Strict in the
--   accumulator.
cfold :: forall w c a. (Members w c, Get w c) => (a -> c -> a) -> a -> System w a

-- | Monadically fold over the game world. Strict in the accumulator.
cfoldM :: forall w c a. (Members w c, Get w c) => (a -> c -> System w a) -> a -> System w a

-- | Monadically fold over the game world. Strict in the accumulator.
cfoldM_ :: forall w c a. (Members w c, Get w c) => (a -> c -> System w a) -> a -> System w ()

-- | Applies a function, if possible.
modify :: forall w c. (Get w c, Set w c) => Entity -> (c -> c) -> System w ()

-- | Destroys component <tt>c</tt> for the given entity. Note that
--   <tt>c</tt> is a phantom argument, used only to convey the type of the
--   entity to be destroyed.
destroy :: forall w c. Destroy w c => Entity -> Proxy c -> System w ()

-- | Returns whether the given entity has component <tt>c</tt> Note that
--   <tt>c</tt> is a phantom argument, used only to convey the type of the
--   entity to be queried.
exists :: forall w c. Get w c => Entity -> Proxy 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 <tt>makeWorld</tt>
data EntityCounter

-- | Writes the given components to a new entity, and yields that entity.
--   The return value is often ignored.
newEntity :: (Set w c, Get w EntityCounter, Set w EntityCounter) => c -> System w Entity

-- | Convenience entity, for use in places where the entity value does not
--   matter, i.e. a global store. Its value is -2, to avoid potential
--   conflicts with caches, which reserve -1.
global :: Entity

-- | <pre>
--   makeWorld "WorldName" [''Component1, ''Component2, ...]
--   </pre>
--   
--   turns into
--   
--   <pre>
--   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 &lt;$&gt; initStore &lt;*&gt; initStore &lt;*&gt; ... &lt;*&gt; initStore
--   </pre>
--   
--   |
makeWorld :: String -> [Name] -> Q [Dec]

-- | Same as makeWorld, but also makes a component instance:
makeWorldAndComponents :: 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 <a>IO</a> monad.
liftIO :: MonadIO m => IO a -> m a

-- | Lift a computation from the argument monad to the constructed monad.
lift :: (MonadTrans t, Monad m) => m a -> t m a
