packages feed

apecs 0.3.0.2 → 0.4.0.0

raw patch · 10 files changed

+260/−236 lines, 10 filesdep ~basePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base

API changes (from Hackage documentation)

- Apecs: initStore :: Store s => IO s
- Apecs: proxy :: forall t. t
- Apecs.Core: EitherStore :: sp -> sq -> EitherStore sp sq
- Apecs.Core: class Store s where {
- Apecs.Core: data EitherStore sp sq
- Apecs.Core: initStore :: Store s => IO s
- Apecs.Core: instance (Apecs.Core.Component p, Apecs.Core.Component q) => Apecs.Core.Component (Data.Either.Either p q)
- Apecs.Core: instance (Apecs.Core.Has w p, Apecs.Core.Has w q) => Apecs.Core.Has w (Data.Either.Either p q)
- Apecs.Core: instance (Apecs.Core.Store sp, Apecs.Core.Store sq) => Apecs.Core.Store (Apecs.Core.EitherStore sp sq)
- Apecs.Core: instance (Apecs.Core.Store t_0, Apecs.Core.Store t_1) => Apecs.Core.Store (t_0, t_1)
- Apecs.Core: 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)
- Apecs.Core: 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)
- Apecs.Core: 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)
- Apecs.Core: 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)
- Apecs.Core: 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)
- Apecs.Core: 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)
- Apecs.Core: instance Apecs.Core.Store Apecs.Core.EntityStore
- Apecs.Core: instance Apecs.Core.Store s => Apecs.Core.Store (Apecs.Core.FilterStore s)
- Apecs.Core: instance Apecs.Core.Store s => Apecs.Core.Store (Apecs.Core.MaybeStore s)
- Apecs.Core: instance Apecs.Core.Store s => Apecs.Core.Store (Apecs.Core.NotStore s)
- Apecs.Core: instance Apecs.Core.Store s => Apecs.Core.Store (Data.Functor.Identity.Identity s)
- Apecs.Stores: instance (GHC.TypeNats.KnownNat n, Apecs.Stores.Cachable s) => Apecs.Core.Store (Apecs.Stores.Cache n s)
- Apecs.Stores: instance Apecs.Core.Store (Apecs.Stores.Map c)
- Apecs.Stores: instance Apecs.Core.Store (Apecs.Stores.Unique c)
- Apecs.Stores: instance GHC.Base.Monoid c => Apecs.Core.Store (Apecs.Stores.Global c)
- Apecs.Util: proxy :: forall t. t
+ Apecs: [unEntity] :: Entity -> Int
+ Apecs: explInit :: ExplInit s => IO s
+ Apecs: makeWorldAndComponents :: String -> [Name] -> Q [Dec]
+ Apecs.Core: [unEntity] :: Entity -> Int
+ Apecs.Core: class ExplDestroy s
+ Apecs.Core: class ExplGet s
+ Apecs.Core: class ExplInit s
+ Apecs.Core: class ExplMembers s
+ Apecs.Core: class ExplSet s
+ Apecs.Core: explInit :: ExplInit s => IO s
+ Apecs.Core: instance (Apecs.Core.ExplDestroy s, Apecs.Core.ExplSet s) => Apecs.Core.ExplSet (Apecs.Core.MaybeStore s)
+ Apecs.Core: instance (Apecs.Core.ExplDestroy t_0, Apecs.Core.ExplDestroy t_1) => Apecs.Core.ExplDestroy (t_0, t_1)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: instance (Apecs.Core.ExplGet t_0, Apecs.Core.ExplGet t_1) => Apecs.Core.ExplGet (t_0, t_1)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: instance (Apecs.Core.ExplMembers t_0, Apecs.Core.ExplGet t_1) => Apecs.Core.ExplMembers (t_0, t_1)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: instance (Apecs.Core.ExplSet t_0, Apecs.Core.ExplSet t_1) => Apecs.Core.ExplSet (t_0, t_1)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: 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)
+ Apecs.Core: instance Apecs.Core.ExplDestroy s => Apecs.Core.ExplDestroy (Data.Functor.Identity.Identity s)
+ Apecs.Core: instance Apecs.Core.ExplDestroy s => Apecs.Core.ExplSet (Apecs.Core.NotStore s)
+ Apecs.Core: instance Apecs.Core.ExplGet Apecs.Core.EntityStore
+ Apecs.Core: instance Apecs.Core.ExplGet s => Apecs.Core.ExplGet (Apecs.Core.FilterStore s)
+ Apecs.Core: instance Apecs.Core.ExplGet s => Apecs.Core.ExplGet (Apecs.Core.MaybeStore s)
+ Apecs.Core: instance Apecs.Core.ExplGet s => Apecs.Core.ExplGet (Apecs.Core.NotStore s)
+ Apecs.Core: instance Apecs.Core.ExplGet s => Apecs.Core.ExplGet (Data.Functor.Identity.Identity s)
+ Apecs.Core: instance Apecs.Core.ExplMembers s => Apecs.Core.ExplMembers (Data.Functor.Identity.Identity s)
+ Apecs.Core: instance Apecs.Core.ExplSet s => Apecs.Core.ExplSet (Data.Functor.Identity.Identity s)
+ Apecs.Core: instance GHC.Num.Num Apecs.Core.Entity
+ Apecs.Core: type Destroy w c = (Has w c, ExplDestroy (Storage c))
+ Apecs.Core: type Get w c = (Has w c, ExplGet (Storage c))
+ Apecs.Core: type Members w c = (Has w c, ExplMembers (Storage c))
+ Apecs.Core: type Set w c = (Has w c, ExplSet (Storage c))
+ Apecs.Stores: instance (Apecs.Core.ExplInit s, GHC.TypeNats.KnownNat n, Apecs.Stores.Cachable s) => Apecs.Core.ExplInit (Apecs.Stores.Cache n s)
+ Apecs.Stores: instance Apecs.Core.ExplDestroy (Apecs.Stores.Map c)
+ Apecs.Stores: instance Apecs.Core.ExplDestroy (Apecs.Stores.Unique c)
+ Apecs.Stores: instance Apecs.Core.ExplDestroy s => Apecs.Core.ExplDestroy (Apecs.Stores.Cache n s)
+ Apecs.Stores: instance Apecs.Core.ExplGet (Apecs.Stores.Global c)
+ Apecs.Stores: instance Apecs.Core.ExplGet (Apecs.Stores.Map c)
+ Apecs.Stores: instance Apecs.Core.ExplGet (Apecs.Stores.Unique c)
+ Apecs.Stores: instance Apecs.Core.ExplGet s => Apecs.Core.ExplGet (Apecs.Stores.Cache n s)
+ Apecs.Stores: instance Apecs.Core.ExplInit (Apecs.Stores.Map c)
+ Apecs.Stores: instance Apecs.Core.ExplInit (Apecs.Stores.Unique c)
+ Apecs.Stores: instance Apecs.Core.ExplMembers (Apecs.Stores.Map c)
+ Apecs.Stores: instance Apecs.Core.ExplMembers (Apecs.Stores.Unique c)
+ Apecs.Stores: instance Apecs.Core.ExplMembers s => Apecs.Core.ExplMembers (Apecs.Stores.Cache n s)
+ Apecs.Stores: instance Apecs.Core.ExplSet (Apecs.Stores.Global c)
+ Apecs.Stores: instance Apecs.Core.ExplSet (Apecs.Stores.Map c)
+ Apecs.Stores: instance Apecs.Core.ExplSet (Apecs.Stores.Unique c)
+ Apecs.Stores: instance Apecs.Core.ExplSet s => Apecs.Core.ExplSet (Apecs.Stores.Cache n s)
+ Apecs.Stores: instance GHC.Base.Monoid c => Apecs.Core.ExplInit (Apecs.Stores.Global c)
+ Apecs.TH: makeWorldAndComponents :: String -> [Name] -> Q [Dec]
- Apecs: class (Elem (Storage c) ~ c, Store (Storage c)) => Component c where {
+ Apecs: class (Elem (Storage c) ~ c) => Component c where {
- Apecs: cmap :: forall world cx cy. (Has world cx, Has world cy) => (cx -> cy) -> System world ()
+ Apecs: cmap :: forall w cx cy. (Get w cx, Members w cx, Set w cy) => (cx -> cy) -> System w ()
- Apecs: cmapM :: forall world c a. Has world c => (c -> System world a) -> System world [a]
+ Apecs: cmapM :: forall w cx cy. (Get w cx, Set w cy, Members w cx) => (cx -> System w cy) -> System w ()
- Apecs: cmapM_ :: forall world c a. Has world c => (c -> System world a) -> System world ()
+ Apecs: cmapM_ :: forall w c a. (Get w c, Members w c) => (c -> System w a) -> System w ()
- Apecs: destroy :: forall w c. Has w c => Entity -> c -> System w ()
+ Apecs: destroy :: forall w c. Destroy w c => Entity -> Proxy c -> System w ()
- Apecs: exists :: forall w c. Has w c => Entity -> c -> System w Bool
+ Apecs: exists :: forall w c. Get w c => Entity -> Proxy c -> System w Bool
- Apecs: get :: forall w c. Has w c => Entity -> System w c
+ Apecs: get :: forall w c. Get w c => Entity -> System w c
- Apecs: getAll :: forall world c. Has world c => System world [c]
+ Apecs: getAll :: forall w c. (Get w c, Members w c) => System w [c]
- Apecs: modify :: forall w c. Has w c => Entity -> (c -> c) -> System w ()
+ Apecs: modify :: forall w c. (Get w c, Set w c) => Entity -> (c -> c) -> System w ()
- Apecs: newEntity :: (Store (Storage c), Has w c, Has w EntityCounter) => c -> System w Entity
+ Apecs: newEntity :: (Set w c, Get w EntityCounter, Set w EntityCounter) => c -> System w Entity
- Apecs: set :: forall w c. Has w c => Entity -> c -> System w ()
+ Apecs: set :: forall w c. Set w c => Entity -> c -> System w ()
- Apecs.Concurrent: pmap :: forall w x y. (Has w y, Has w x) => Int -> (x -> y) -> System w ()
+ Apecs.Concurrent: pmap :: forall w cx cy. (Get w cx, Members w cx, Set w cy) => Int -> (cx -> cy) -> System w ()
- Apecs.Core: class (Elem (Storage c) ~ c, Store (Storage c)) => Component c where {
+ Apecs.Core: class (Elem (Storage c) ~ c) => Component c where {
- Apecs.Core: explDestroy :: Store s => s -> Int -> IO ()
+ Apecs.Core: explDestroy :: ExplDestroy s => s -> Int -> IO ()
- Apecs.Core: explExists :: Store s => s -> Int -> IO Bool
+ Apecs.Core: explExists :: ExplGet s => s -> Int -> IO Bool
- Apecs.Core: explGet :: Store s => s -> Int -> IO (Elem s)
+ Apecs.Core: explGet :: ExplGet s => s -> Int -> IO (Elem s)
- Apecs.Core: explMembers :: Store s => s -> IO (Vector Int)
+ Apecs.Core: explMembers :: ExplMembers s => s -> IO (Vector Int)
- Apecs.Core: explSet :: Store s => s -> Int -> Elem s -> IO ()
+ Apecs.Core: explSet :: ExplSet s => s -> Int -> Elem s -> IO ()
- Apecs.Core: type family Elem s;
+ Apecs.Core: type family Storage c;
- Apecs.Stores: class Store s => Cachable s
+ Apecs.Stores: class Cachable s
- Apecs.System: cmap :: forall world cx cy. (Has world cx, Has world cy) => (cx -> cy) -> System world ()
+ Apecs.System: cmap :: forall w cx cy. (Get w cx, Members w cx, Set w cy) => (cx -> cy) -> System w ()
- Apecs.System: cmapM :: forall world c a. Has world c => (c -> System world a) -> System world [a]
+ Apecs.System: cmapM :: forall w cx cy. (Get w cx, Set w cy, Members w cx) => (cx -> System w cy) -> System w ()
- Apecs.System: cmapM_ :: forall world c a. Has world c => (c -> System world a) -> System world ()
+ Apecs.System: cmapM_ :: forall w c a. (Get w c, Members w c) => (c -> System w a) -> System w ()
- Apecs.System: count :: forall w c. Has w c => c -> System w Int
+ Apecs.System: count :: forall w c. Members w c => c -> System w Int
- Apecs.System: destroy :: forall w c. Has w c => Entity -> c -> System w ()
+ Apecs.System: destroy :: forall w c. Destroy w c => Entity -> Proxy c -> System w ()
- Apecs.System: exists :: forall w c. Has w c => Entity -> c -> System w Bool
+ Apecs.System: exists :: forall w c. Get w c => Entity -> Proxy c -> System w Bool
- Apecs.System: get :: forall w c. Has w c => Entity -> System w c
+ Apecs.System: get :: forall w c. Get w c => Entity -> System w c
- Apecs.System: getAll :: forall world c. Has world c => System world [c]
+ Apecs.System: getAll :: forall w c. (Get w c, Members w c) => System w [c]
- Apecs.System: modify :: forall w c. Has w c => Entity -> (c -> c) -> System w ()
+ Apecs.System: modify :: forall w c. (Get w c, Set w c) => Entity -> (c -> c) -> System w ()
- Apecs.System: set :: forall w c. Has w c => Entity -> c -> System w ()
+ Apecs.System: set :: forall w c. Set w c => Entity -> c -> System w ()
- Apecs.Util: newEntity :: (Store (Storage c), Has w c, Has w EntityCounter) => c -> System w Entity
+ Apecs.Util: newEntity :: (Set w c, Get w EntityCounter, Set w EntityCounter) => c -> System w Entity

Files

README.md view
@@ -1,10 +1,10 @@ # apecs [![Build Status](https://travis-ci.org/jonascarpay/apecs.svg?branch=master)](https://travis-ci.org/jonascarpay/apecs) [![Hackage](https://img.shields.io/hackage/v/apecs.svg)](https://hackage.haskell.org/package/apecs)-[![apecs on Stackage LTS 10](http://stackage.org/package/apecs/badge/lts-10)](http://stackage.org/lts-10/package/apecs)+[![apecs on Stackage LTS 11](http://stackage.org/package/apecs/badge/lts-11)](http://stackage.org/lts-10/package/apecs) -apecs is an _Entity Component System_ inspired by [specs](https://github.com/slide-rs/specs) and [Entitas](https://github.com/sschmid/Entitas-CSharp).-It provides a collection of mutable component stores, and an expressive DSL for operating on those stores, both easily extended.+apecs is an _Entity Component System_ framework inspired by [specs](https://github.com/slide-rs/specs) and [Entitas](https://github.com/sschmid/Entitas-CSharp).+The front-end DSL allows you to concisely express your game logic, with an efficient back-end storage framework that can be extended to meet any performance needs.  #### Links - [documentation](https://hackage.haskell.org/package/apecs/docs/Apecs.html)
apecs.cabal view
@@ -1,5 +1,5 @@ name:                apecs-version:             0.3.0.2+version:             0.4.0.0 homepage:            https://github.com/jonascarpay/apecs#readme license:             BSD3 license-file:        LICENSE@@ -53,6 +53,8 @@     base >= 4.7 && < 5,     apecs,     QuickCheck,+    criterion,+    linear,     containers,     vector   default-language:
src/Apecs.hs view
@@ -3,12 +3,13 @@ It selectively re-exports the user-facing functions from the submodules. -} module Apecs (+  module Data.Proxy,   -- * Core types     System(..), Component(..), Entity(..), Has(..), Not(..),    -- * Stores     Map, Unique, Global, Cache,-    initStore,+    explInit,    -- * Systems     get, set, getAll,@@ -17,14 +18,15 @@    -- * Other     runSystem, runWith,-    runGC, EntityCounter, newEntity, global, proxy,-    makeWorld,+    runGC, EntityCounter, newEntity, global,+    makeWorld, makeWorldAndComponents,    -- * Re-exports     asks, ask, liftIO, lift, ) where  import           Control.Monad.Reader (ask, asks, lift, liftIO)+import           Data.Proxy  import           Apecs.Stores import           Apecs.System
src/Apecs/Concurrent.hs view
@@ -23,12 +23,12 @@  -- | Parallel version of @cmap@.  {-# INLINE pmap #-}-pmap :: forall w x y. (Has w y, Has w x)+pmap :: forall w cx cy. (Get w cx, Members w cx, Set w cy)      => Int -- ^ Entities per thread-     -> (x -> y) -> System w ()+     -> (cx -> cy) -> System w () pmap grainSize f =-  do sr :: Storage x <- getStore-     sw :: Storage y <- getStore+  do sr :: Storage cx <- getStore+     sw :: Storage cy <- getStore      liftIO$ do        sl <- explMembers sr        parallelize grainSize (\e -> explGet sr e >>= explSet sw e . f) sl
src/Apecs/Core.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE ConstraintKinds            #-} {-# LANGUAGE FlexibleContexts           #-} {-# LANGUAGE FlexibleInstances          #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}@@ -11,54 +12,58 @@  import           Control.Monad.Reader import           Data.Functor.Identity-import qualified Data.Vector.Unboxed  as U+import qualified Data.Vector.Unboxed   as U -import qualified Apecs.THTuples       as T+import qualified Apecs.THTuples        as T --- | An Entity is really just an Int in a newtype, used to index into a component store.-newtype Entity = Entity Int deriving (Eq, Ord, Show)+-- | An Entity is just an integer, used to index into a component store.+newtype Entity = Entity {unEntity :: Int} deriving (Num, Eq, Ord, Show) --- | A system is a newtype around `ReaderT w IO a`, where `w` is the game world variable.+-- | A System is a newtype around `ReaderT w IO a`, where `w` is the game world variable. newtype System w a = System {unSystem :: ReaderT w IO a} deriving (Functor, Monad, Applicative, MonadIO)  -- | 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+class (Elem (Storage c) ~ c) => Component c where   type Storage c  -- | A world `Has` a component if it can produce its Storage class Component c => Has w c where   getStore :: 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-  -- | The type of components stored by this Store-  type Elem s+-- | The type of components stored by a Store+type family Elem s +-- | Holds components indexed by entities+class ExplInit s where   -- | Initialize the store with its initialization arguments.-  initStore :: IO s+  explInit :: IO s -  -- | Writes a component-  explSet :: s -> Int -> Elem s -> IO ()+-- | Stores that support @get@ and @exists@ in the IO monad+--   If @existsIO@+class ExplGet s where   -- | Reads a component from the store. What happens if the component does not exist is left undefined.   explGet :: s -> Int -> IO (Elem s)+  -- | Returns whether there is a component for the given index+  explExists :: s -> Int -> IO Bool++class ExplSet s where+  -- | Writes a component+  explSet :: s -> Int -> Elem s -> IO ()++class ExplDestroy s where   -- | Destroys the component for a given index.   explDestroy :: s -> Int -> IO ()++class ExplMembers s where   -- | Returns an unboxed vector of member indices   explMembers :: s -> IO (U.Vector Int) -  -- | Returns whether there is a component for the given index-  explExists :: s -> Int -> IO Bool-  explExists s n = do-    mems <- explMembers s-    return $ U.elem n mems+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))  instance Component c => Component (Identity c) where   type Storage (Identity c) = Identity (Storage c)@@ -66,18 +71,23 @@ instance Has w c => Has w (Identity c) where   getStore = Identity <$> getStore -instance Store s => Store (Identity s) where-  type Elem (Identity s) = Identity (Elem s)-  initStore = error "Initializing Pseudostore"+type instance Elem (Identity s) = Identity (Elem s)++instance ExplGet s => ExplGet (Identity s) where   explGet (Identity s) e = Identity <$> explGet s e-  explSet (Identity s) e (Identity x) = explSet s e x   explExists  (Identity s) = explExists s++instance ExplSet s => ExplSet (Identity s) where+  explSet (Identity s) e (Identity x) = explSet s e x+instance ExplMembers s => ExplMembers (Identity s) where   explMembers (Identity s) = explMembers s+instance ExplDestroy s => ExplDestroy (Identity s) where   explDestroy (Identity s) = explDestroy s --- Tuple Instances+-- Tuple Instances TODO T.makeInstances [2..8] + -- | Psuedocomponent indicating the absence of @a@. data Not a = Not @@ -90,15 +100,15 @@ instance (Has w c) => Has w (Not c) where   getStore = NotStore <$> getStore -instance Store s => Store (NotStore s) where-  type Elem (NotStore s) = Not (Elem s)-  initStore = error "Initializing Pseudostore"+type instance Elem (NotStore s) = Not (Elem s)++instance ExplGet s => ExplGet (NotStore s) where   explGet _ _ = return Not-  explSet (NotStore sa) ety _ = explDestroy sa ety   explExists (NotStore sa) ety = not <$> explExists sa ety-  explMembers _ = return mempty-  explDestroy sa ety = explSet sa ety Not +instance ExplDestroy s => ExplSet (NotStore s) where+  explSet (NotStore sa) ety _ = explDestroy sa ety+ -- | Pseudostore used to produce values of type @Maybe a@ newtype MaybeStore s = MaybeStore s instance Component c => Component (Maybe c) where@@ -107,42 +117,18 @@ instance (Has w c) => Has w (Maybe c) where   getStore = MaybeStore <$> getStore -instance Store s => Store (MaybeStore s) where-  type Elem (MaybeStore s) = Maybe (Elem s)-  initStore = error "Initializing Pseudostore"+type instance Elem (MaybeStore s) = Maybe (Elem s)++instance ExplGet s => ExplGet (MaybeStore s) where   explGet (MaybeStore sa) ety = do     e <- explExists sa ety     if e then Just <$> explGet sa ety          else return Nothing-  explSet (MaybeStore sa) ety Nothing = explDestroy sa ety-  explSet (MaybeStore sa) ety (Just x) = explSet sa ety x   explExists _ _ = return True-  explMembers _ = return mempty-  explDestroy (MaybeStore sa) ety = explDestroy sa ety --- | Pseudostore used to produce values of type @Either p q@-data EitherStore sp sq = EitherStore sp sq-instance (Component p, Component q) => Component (Either p q) where-  type Storage (Either p q) = EitherStore (Storage p) (Storage q)--instance (Has w p, Has w q) => Has w (Either p q) where-  getStore = EitherStore <$> getStore <*> getStore--instance (Store sp, Store sq) => Store (EitherStore sp sq) where-  type Elem (EitherStore sp sq) = Either (Elem sp) (Elem sq)-  initStore = error "Initializing Pseudostore"-  explGet (EitherStore sp sq) ety = do-    e <- explExists sp ety-    if e then Left <$> explGet sp ety-         else Right <$> explGet sq ety-  explSet (EitherStore sp _) ety (Left p) = explSet sp ety p-  explSet (EitherStore _ sq) ety (Right q) = explSet sq ety q-  explExists (EitherStore sp sq) ety = do-    e <- explExists sp ety-    if e then return True-         else explExists sq ety-  explMembers _ = return mempty-  explDestroy _ _ = return ()+instance (ExplDestroy s, ExplSet s) => ExplSet (MaybeStore s) where+  explSet (MaybeStore sa) ety Nothing  = explDestroy sa ety+  explSet (MaybeStore sa) ety (Just x) = explSet sa ety x  data Filter c = Filter deriving (Eq, Show) newtype FilterStore s = FilterStore s@@ -153,14 +139,11 @@ instance Has w c => Has w (Filter c) where   getStore = FilterStore <$> getStore -instance Store s => Store (FilterStore s) where-  type Elem (FilterStore s) = Filter (Elem s)-  initStore = error "Initializing Pseudostore"+type instance Elem (FilterStore s) = Filter (Elem s)++instance ExplGet s => ExplGet (FilterStore s) where   explGet _ _ = return Filter-  explSet _ _ _ = return ()   explExists (FilterStore s) ety = explExists s ety-  explMembers (FilterStore s) = explMembers s-  explDestroy _ _ = return ()  -- | Pseudostore used to produce components of type @Entity@ data EntityStore = EntityStore@@ -170,11 +153,7 @@ instance (Has w Entity) where   getStore = return EntityStore -instance Store EntityStore where-  type Elem EntityStore = Entity-  initStore = error "Initializing Pseudostore"+type instance Elem EntityStore = Entity+instance ExplGet EntityStore where   explGet _ ety = return $ Entity ety-  explSet _ _ _ = liftIO$ putStrLn "Warning: Writing Entity is undefined"   explExists _ _ = return True-  explMembers _ = return mempty-  explDestroy _ _ = return ()
src/Apecs/Stores.hs view
@@ -28,97 +28,93 @@  -- | A map based on @Data.Intmap.Strict@. O(log(n)) for most operations. newtype Map c = Map (IORef (M.IntMap c))-instance Store (Map c) where-  type Elem (Map c) = c-  initStore = Map <$> newIORef mempty-  explGet     (Map ref) ety   = fromJust . M.lookup ety <$> readIORef ref-  explSet     (Map ref) ety x = modifyIORef' ref $ M.insert ety x-  explExists  (Map ref) ety   = M.member ety <$> readIORef ref-  explDestroy (Map ref) ety   = modifyIORef' ref (M.delete ety)-  explMembers (Map ref)       = U.fromList . M.keys <$> readIORef ref++type instance Elem (Map c) = c+instance ExplInit (Map c) where+  explInit = Map <$> newIORef mempty++instance ExplGet (Map c) where+  explExists (Map ref) ety = M.member ety <$> readIORef ref+  explGet    (Map ref) ety = fromJust . M.lookup ety <$> readIORef ref+  {-# INLINE explExists #-}   {-# INLINE explGet #-}++instance ExplSet (Map c) where   {-# INLINE explSet #-}+  explSet (Map ref) ety x = modifyIORef' ref $ M.insert ety x++instance ExplDestroy (Map c) where   {-# INLINE explDestroy #-}+  explDestroy (Map ref) ety = modifyIORef' ref (M.delete ety)++instance ExplMembers (Map c) where   {-# INLINE explMembers #-}-  {-# INLINE explExists #-}+  explMembers (Map ref) = U.fromList . M.keys <$> readIORef ref  -- | 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 = Unique (IORef Int) (IORef c)-instance Store (Unique c) where-  type Elem (Unique c) = c-  initStore = Unique <$> newIORef (-1) <*> newIORef (error "Uninitialized Unique value")-  explGet     (Unique _ cref) _ = readIORef cref-  explSet     (Unique eref cref) ety x = writeIORef eref ety >> writeIORef cref x+type instance Elem (Unique c) = c+instance ExplInit (Unique c) where+  explInit = Unique <$> newIORef (-1) <*> newIORef (error "Uninitialized Unique value")++instance ExplGet (Unique c) where+  {-# INLINE explGet #-}+  explGet (Unique _ cref) _ = readIORef cref+  {-# INLINE explExists #-}+  explExists (Unique eref _) ety = (==ety) <$> readIORef eref++instance ExplSet (Unique c) where+  {-# INLINE explSet #-}+  explSet (Unique eref cref) ety x = writeIORef eref ety >> writeIORef cref x++instance ExplDestroy (Unique c) where+  {-# INLINE explDestroy #-}   explDestroy (Unique eref _) ety = do e <- readIORef eref; when (e==ety) (writeIORef eref (-1))++instance ExplMembers (Unique c) where+  {-# INLINE explMembers #-}   explMembers (Unique eref _) = f <$> readIORef eref     where f (-1) = mempty           f x    = U.singleton x-  explExists  (Unique eref _) ety = (==ety) <$> readIORef eref-  {-# INLINE explDestroy #-}-  {-# INLINE explMembers #-}-  {-# INLINE explExists #-}-  {-# INLINE explSet #-}-  {-# INLINE explGet #-}  -- | 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. newtype Global c = Global (IORef c)-instance Monoid c => Store (Global c) where-  type Elem   (Global c) = c-  initStore = Global <$> newIORef mempty-  explGet (Global ref) _   = readIORef ref+type instance Elem (Global c) = c+instance Monoid c => ExplInit (Global c) where+  explInit = Global <$> newIORef mempty++instance ExplGet (Global c) where+  explGet (Global ref) _ = readIORef ref+  explExists _ _ = return True++instance ExplSet (Global c) where   explSet (Global ref) _ c = writeIORef ref c-  explExists  _ _ = return True-  explDestroy s _ = explSet s 0 mempty-  explMembers _ = return $ U.singleton (-1)-  {-# INLINE explDestroy #-}-  {-# INLINE explMembers #-}-  {-# INLINE explExists #-}-  {-# INLINE explSet #-}-  {-# INLINE explGet #-} +-- | An empty type class indicating that the store behaves like a regular map, and can therefore safely be cached.+class Cachable s+instance Cachable (Map s)+instance (KnownNat n, Cachable s) => Cachable (Cache n s)+ -- | 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 =   Cache Int (UM.IOVector Int) (VM.IOVector (Elem s)) s---- | 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 Cachable (Map s)-instance (KnownNat n, Cachable s) => Cachable (Cache n s)+type instance Elem (Cache n s) = Elem s -instance (KnownNat n, Cachable s) => Store (Cache n s) where-  type Elem (Cache n s) = Elem s-  initStore = do+instance (ExplInit s, KnownNat n, Cachable s) => ExplInit (Cache n s) where+  explInit = do     let n = fromIntegral$ natVal (Proxy @n)     tags <- UM.replicate n (-1)     cache <- VM.new n-    child <- initStore+    child <- explInit     return (Cache n tags cache child) -  {-# INLINE explDestroy #-}-  explDestroy (Cache n tags _ s) ety = do-    tag <- UM.unsafeRead tags (ety `rem` n)-    if tag == ety-       then UM.unsafeWrite tags (ety `rem` n) (-1)-       else explDestroy s ety--  {-# INLINE explExists #-}-  explExists (Cache n tags _ s) ety = do-    tag <- UM.unsafeRead tags (ety `rem` n)-    if tag == ety then return True else explExists s ety--  {-# INLINE explMembers #-}-  explMembers (Cache _ tags _ s) = do-    cached <- U.filter (/= (-1)) <$> U.freeze tags-    stored <- explMembers s-    return $! cached U.++ stored--  {-# INLINE explGet #-}+instance ExplGet s => ExplGet (Cache n s) where   explGet (Cache n tags cache s) ety = do     let index = ety `rem` n     tag <- UM.unsafeRead tags index@@ -126,7 +122,11 @@        then VM.unsafeRead cache index        else explGet s ety -  {-# INLINE explSet #-}+  explExists (Cache n tags _ s) ety = do+    tag <- UM.unsafeRead tags (ety `rem` n)+    if tag == ety then return True else explExists s ety++instance ExplSet s => ExplSet (Cache n s) where   explSet (Cache n tags cache s) ety x = do     let index = ety `rem` n     tag <- UM.unsafeRead tags index@@ -135,3 +135,16 @@       explSet s tag cached     UM.unsafeWrite tags  index ety     VM.unsafeWrite cache index x++instance ExplDestroy s => ExplDestroy (Cache n s) where+  explDestroy (Cache n tags _ s) ety = do+    tag <- UM.unsafeRead tags (ety `rem` n)+    if tag == ety+       then UM.unsafeWrite tags (ety `rem` n) (-1)+       else explDestroy s ety++instance ExplMembers s => ExplMembers (Cache n s) where+  explMembers (Cache _ tags _ s) = do+    cached <- U.filter (/= (-1)) <$> U.freeze tags+    stored <- explMembers s+    return $! cached U.++ stored
src/Apecs/System.hs view
@@ -7,6 +7,7 @@ module Apecs.System where  import           Control.Monad.Reader+import           Data.Proxy import qualified Data.Vector.Unboxed  as U  import           Apecs.Core@@ -22,7 +23,7 @@ runWith = flip runSystem  {-# INLINE get #-}-get :: forall w c. Has w c => Entity -> System w c+get :: forall w c. Get w c => Entity -> System w c get (Entity ety) = do   s :: Storage c <- getStore   liftIO$ explGet s ety@@ -31,7 +32,7 @@ --   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' {-# INLINE set #-}-set :: forall w c. Has w c => Entity -> c -> System w ()+set :: forall w c. Set w c => Entity -> c -> System w () set (Entity ety) x = do   s :: Storage c <- getStore   liftIO$ explSet s ety x@@ -39,39 +40,41 @@ -- | 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. {-# INLINE exists #-}-exists :: forall w c. Has w c => Entity -> c -> System w Bool-exists (Entity ety) ~_ = do+exists :: forall w c. Get w c => Entity -> Proxy c -> System w Bool+exists (Entity ety) _ = do   s :: Storage c <- getStore   liftIO$ explExists s ety  -- | Maps a function over all entities with a @cx@, and writes their @cy@ {-# INLINE cmap #-}-cmap :: forall world cx cy. (Has world cx, Has world cy)-     => (cx -> cy) -> System world ()+cmap :: forall w cx cy. (Get w cx, Members w cx, Set w cy)+     => (cx -> cy) -> System w () cmap f = do   sx :: Storage cx <- getStore   sy :: Storage cy <- getStore   liftIO$ do-    sl <- liftIO$ explMembers sx+    sl <- explMembers sx     U.forM_ sl $ \ e -> do       r <- explGet sx e       explSet sy e (f r) --- | Monadically iterates over all entites with a cx+-- | Monadically iterates over all entites with a cx, and writes their cy {-# INLINE cmapM #-}-cmapM :: forall world c a. Has world c-      => (c -> System world a) -> System world [a]+cmapM :: forall w cx cy. (Get w cx, Set w cy, Members w cx)+      => (cx -> System w cy) -> System w () cmapM sys = do-  s :: Storage c <- getStore-  sl <- liftIO$ explMembers s-  forM (U.toList sl) $ \ ety -> do-    x <- liftIO$ explGet s ety-    sys x+  sx :: Storage cx <- getStore+  sy :: Storage cy <- getStore+  sl <- liftIO$ explMembers sx+  U.forM_ sl $ \ e -> do+    x <- liftIO$ explGet sx e+    y <- sys x+    liftIO$ explSet sy e y  -- | Monadically iterates over all entites with a cx {-# INLINE cmapM_ #-}-cmapM_ :: forall world c a. Has world c-       => (c -> System world a) -> System world ()+cmapM_ :: forall w c a. (Get w c, Members w c)+       => (c -> System w a) -> System w () cmapM_ sys = do   s :: Storage c <- getStore   sl <- liftIO$ explMembers s@@ -82,8 +85,8 @@ -- | Get all components @c@. --   Call as @[(c,Entity)]@ to read the entity/index. {-# INLINE getAll #-}-getAll :: forall world c. Has world c-      => System world [c]+getAll :: forall w c. (Get w c, Members w c)+      => System w [c] getAll = do   s :: Storage c <- getStore   sl <- liftIO$ explMembers s@@ -93,14 +96,14 @@ -- | 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. {-# INLINE destroy #-}-destroy :: forall w c. Has w c => Entity -> c -> System w ()-destroy (Entity ety) ~_ = do+destroy :: forall w c. Destroy w c => Entity -> Proxy c -> System w ()+destroy (Entity ety) _ = do   s :: Storage c <- getStore   liftIO$ explDestroy s ety  -- | Applies a function, if possible. {-# INLINE modify #-}-modify :: forall w c. Has w c => Entity -> (c -> c) -> System w ()+modify :: forall w c. (Get w c, Set w c) => Entity -> (c -> c) -> System w () modify (Entity ety) f = do   s :: Storage c <- getStore   liftIO$ do@@ -109,7 +112,7 @@  -- | Counts the number of entities with a @c@ {-# INLINE count #-}-count :: forall w c. Has w c => c -> System w Int+count :: forall w c. Members w c => c -> System w Int count ~_ = do   s :: Storage c <- getStore   sl <- liftIO$ explMembers s
src/Apecs/TH.hs view
@@ -1,11 +1,14 @@ {-# LANGUAGE TemplateHaskell #-}  module Apecs.TH-  ( makeWorld, makeWorldNoEC-  )where+  ( makeWorld, makeWorldNoEC, makeWorldAndComponents+  ) where  import           Language.Haskell.TH+import           Control.Monad +import           Apecs.Core+import           Apecs.Stores import           Apecs.Util          (EntityCounter)  genName :: String -> Q Name@@ -14,7 +17,9 @@ -- | Same as 'makeWorld', but has no 'EntityCounter' makeWorldNoEC :: String -> [Name] -> Q [Dec] makeWorldNoEC worldName cTypes = do-  cTypesNames <- mapM (\t -> do rec <- genName "rec"; return (ConT t, rec)) cTypes+  cTypesNames <- forM cTypes $ \t -> do+    rec <- genName "rec"+    return (ConT t, rec)    let wld = mkName worldName       has = mkName "Has"@@ -34,13 +39,25 @@       initWorldName = mkName $ "init" ++ worldName       initSig = SigD initWorldName (AppT (ConT (mkName "IO")) (ConT wld))       initDecl = FunD initWorldName [Clause []-        (NormalB$ iterate (\wE -> AppE (AppE (VarE $ mkName "<*>") wE) (VarE $ mkName "initStore")) (AppE (VarE $ mkName "return") (ConE wld)) !! length records)+        (NormalB$ iterate (\wE -> AppE (AppE (VarE $ mkName "<*>") wE) (VarE $ mkName "explInit")) (AppE (VarE $ mkName "return") (ConE wld)) !! length records)         [] ]        hasDecl = makeInstance <$> cTypesNames    return $ wldDecl : initSig : initDecl : hasDecl +makeComponent :: Name -> Q Dec+makeComponent comp = do+  let ct = return$ ConT comp+  head <$> [d| instance Component $ct where type Storage $ct = Map $ct |]+  +-- | Same as makeWorld, but also makes a component instance:+makeWorldAndComponents :: String -> [Name] -> Q [Dec]+makeWorldAndComponents worldName cTypes = do+  wdecls <- makeWorld worldName cTypes+  cdecls <- mapM makeComponent cTypes+  return $ wdecls ++ cdecls+   {-|  > makeWorld "WorldName" [''Component1, ''Component2, ...]@@ -59,4 +76,3 @@ |-} makeWorld :: String -> [Name] -> Q [Dec] makeWorld worldName cTypes = makeWorldNoEC worldName (cTypes ++ [''EntityCounter])-
src/Apecs/THTuples.hs view
@@ -5,46 +5,48 @@ import qualified Data.Vector.Unboxed as U import           Language.Haskell.TH --- | Generate tuple instances for the following tuple sizes.-makeInstances :: [Int] -> Q [Dec]-makeInstances is = concat <$> traverse tupleInstances is- {---instance (Component a, Component b) => Component (a,b) where+instance (Component a, Component b) => Component (a, b) where   type Storage (a,b) = (Storage a, Storage b)  instance (Has w a, Has w b) => Has w (a,b) where-  {-# INLINE getStore #-}-  getStore = (,) <$> getStore <*> getStore+  getStore = liftM2 (,) getStore getStore -instance (Store a, Store b) => Store (a,b) where-  type Elem (a, b) = (Elem a, Elem b)-  type SafeRW (a, b) = (SafeRW a, SafeRW b)-  initStore = (,) <$> initStore <*> initStore+type instance Elem (a,b) = (Elem a, Elem b) -  explSet       (sa,sb) ety (wa,wb) = explSet sa ety wa >> explSet sb ety wb-  explDestroy   (sa,sb) ety = explDestroy sa ety >> explDestroy sb ety-  explExists    (sa,sb) ety = explExists sa ety >>= \case False -> return False-                                                          True  -> explExists sb ety-  explMembers   (sa,sb) = explMembers sa >>= U.filterM (explExists sb)-  {-# INLINE explGet #-}-  {-# INLINE explSet #-}-  {-# INLINE explMembers #-}-  {-# INLINE explDestroy #-}-  {-# INLINE explExists #-}+instance (ExplGet a, ExplGet b) => ExplGet (a, b) where+  explExists (sa, sb) ety = liftM2 (&&) (explExists sa ety) (explExists sb ety)+  explGet (sa, sb) ety = liftM2 (,) (explGet sa ety) (explGet sb ety)++instance (ExplSet a, ExplSet b) => ExplSet (a, b) where+  explSet (sa,sb) ety (a,b) = explSet sa ety a >> explSet sb ety b++instance (ExplDestroy a, ExplDestroy b) => ExplDestroy (a, b) where+  explDestroy (sa, sb) ety = explDestroy sa ety >> explDestroy sb ety++instance (ExplMembers a, ExplGet b) => ExplMembers (a, b) where+  explMembers (sa, sb) = explMembers sa >>= U.filterM (explExists sb) --}++-- | Generate tuple instances for the following tuple sizes.+makeInstances :: [Int] -> Q [Dec]+makeInstances is = concat <$> traverse tupleInstances is+ tupleInstances :: Int -> Q [Dec] tupleInstances n = do   let vars = [ VarT . mkName $ "t_" ++ show i | i <- [0..n-1]]+       tupleUpT :: [Type] -> Type       tupleUpT = foldl AppT (TupleT n)       varTuple :: Type       varTuple = tupleUpT vars+       tupleName :: Name       tupleName = tupleDataName n       tuplE :: Exp       tuplE = ConE tupleName +      -- Component       compN = mkName "Component"       compT var = ConT compN `AppT` var       strgN = mkName "Storage"@@ -54,6 +56,7 @@           TySynEqn [varTuple] (tupleUpT . fmap strgT $ vars)         ] +      -- Has       hasN = mkName "Has"       hasT var = ConT hasN `AppT` VarT (mkName "w") `AppT` var       getStoreN = mkName "getStore"@@ -70,12 +73,12 @@       sequenceAll :: [Exp] -> Exp       sequenceAll = foldl1 (\a x -> AppE (AppE (VarE$ mkName ">>") a) x) -      strN  = mkName "Store"-      strsN = mkName "Elem"--      strT  var = ConT strN  `AppT` var-      strsT var = ConT strsN `AppT` var+      -- Elem+      elemN = mkName "Elem"+      elemT var = ConT elemN `AppT` var+      elemI = TySynInstD elemN $ TySynEqn [varTuple] (tupleUpT $ fmap elemT vars) +      -- s, ety, w arguments       sNs = [ mkName $ "s_" ++ show i | i <- [0..n-1]]       sPat = ConP tupleName (VarP <$> sNs)       sEs = VarE <$> sNs@@ -86,12 +89,21 @@       wPat = ConP tupleName (VarP <$> wNs)       wEs = VarE <$> wNs +      getN     = mkName "ExplGet"+      setN     = mkName "ExplSet"+      membersN = mkName "ExplMembers"+      destroyN = mkName "ExplDestroy"++      getT var     = ConT getN `AppT` var+      setT var     = ConT setN `AppT` var+      membersT var = ConT membersN `AppT` var+      destroyT var = ConT destroyN `AppT` var+       explSetN     = mkName "explSet"       explDestroyN = mkName "explDestroy"       explExistsN  = mkName "explExists"       explMembersN = mkName "explMembers"       explGetN     = mkName "explGet"-      initStoreN   = mkName "initStore"        explSetE     = VarE explSetN       explDestroyE = VarE explDestroyN@@ -99,46 +111,46 @@       explMembersE = VarE explMembersN       explGetE     = VarE explGetN -      explSetF sE wE = AppE explSetE sE `AppE` etyE `AppE` wE+      explSetF sE wE  = AppE explSetE sE `AppE` etyE `AppE` wE       explDestroyF sE = AppE explDestroyE sE `AppE` etyE-      explExistsF sE = AppE explExistsE sE+      explExistsF sE  = AppE explExistsE sE       explMembersF sE = AppE explMembersE sE-      explGetF sE = AppE explGetE sE `AppE` etyE+      explGetF sE     = AppE explGetE sE `AppE` etyE -      explExistsAnd va vb = AppE (AppE (VarE '(>>=)) va)-                                 (LamCaseE [ Match (ConP 'False []) (NormalB$ AppE (VarE 'return) (ConE 'False)) []-                                           , Match (ConP 'True []) (NormalB vb) []-                                           ])+      explExistsAnd va vb =+        AppE (AppE (VarE '(>>=)) va)+          (LamCaseE [ Match (ConP 'False []) (NormalB$ AppE (VarE 'return) (ConE 'False)) []+                    , Match (ConP 'True []) (NormalB vb) []+                    ])        explMembersFold va vb = AppE (VarE '(>>=)) va `AppE` AppE (VarE 'U.filterM) vb -      strI = InstanceD Nothing (strT <$> vars) (strT varTuple)-        [ TySynInstD strsN $ TySynEqn [varTuple] (tupleUpT $ fmap strsT vars)+      getI = InstanceD Nothing (getT <$> vars) (getT varTuple)+        [ FunD explGetN [Clause [sPat, etyPat]+            (NormalB$ liftAll tuplE (explGetF <$> sEs)) [] ]+        , PragmaD$ InlineP explGetN Inline FunLike AllPhases -        , FunD explSetN [Clause [sPat, etyPat, wPat]+        , FunD explExistsN [Clause [sPat, etyPat]+            (NormalB$ foldr explExistsAnd (AppE (VarE 'pure) (ConE 'True)) ((`AppE` etyE) . explExistsF <$> sEs)) [] ]+        , PragmaD$ InlineP explExistsN Inline FunLike AllPhases+        ]++      setI = InstanceD Nothing (setT <$> vars) (setT varTuple)+        [ FunD explSetN [Clause [sPat, etyPat, wPat]             (NormalB$ sequenceAll (zipWith explSetF sEs wEs)) [] ]         , PragmaD$ InlineP explSetN Inline FunLike AllPhases+        ] -        , FunD explDestroyN [Clause [sPat, etyPat]+      destroyI = InstanceD Nothing (destroyT <$> vars) (destroyT varTuple)+        [ FunD explDestroyN [Clause [sPat, etyPat]             (NormalB$ sequenceAll (explDestroyF <$> sEs)) [] ]         , PragmaD$ InlineP explDestroyN Inline FunLike AllPhases--        , FunD explExistsN [Clause [sPat, etyPat]-            (NormalB$ foldr explExistsAnd (AppE (VarE 'pure) (ConE 'True)) ((`AppE` etyE) . explExistsF <$> sEs)) [] ]-        , PragmaD$ InlineP explExistsN Inline FunLike AllPhases+        ] -        , FunD explMembersN [Clause [sPat]+      membersI = InstanceD Nothing (membersT (head vars) : (getT <$> tail vars)) (membersT varTuple)+        [ FunD explMembersN [Clause [sPat]             (NormalB$ foldl explMembersFold (explMembersF (head sEs)) (explExistsF <$> tail sEs)) [] ]         , PragmaD$ InlineP explMembersN Inline FunLike AllPhases--        , FunD explGetN [Clause [sPat, etyPat]-            (NormalB$ liftAll tuplE (explGetF <$> sEs)) [] ]-        , PragmaD$ InlineP explGetN Inline FunLike AllPhases--        , FunD initStoreN [Clause []-            (NormalB$ liftAll tuplE (VarE initStoreN <$ sEs)) [] ]-        , PragmaD$ InlineP initStoreN Inline FunLike AllPhases-         ] -  return [compI, hasI, strI]+  return [compI, hasI, elemI, getI, setI, destroyI, membersI]
src/Apecs/Util.hs view
@@ -8,7 +8,7 @@  module Apecs.Util (   -- * Utility-  runGC, global, proxy,+  runGC, global,    -- * EntityCounter   EntityCounter, nextEntity, newEntity,@@ -25,6 +25,7 @@ import           Control.Applicative  (liftA2) import           Control.Monad.Reader (liftIO) import           Data.Monoid+import           Data.Proxy import           System.CPUTime import           System.Mem           (performMajorGC) @@ -36,10 +37,6 @@ global :: Entity global = Entity (-1) --- | Convenience proxy value-proxy :: forall t. t-proxy = error "Proxy value"- -- | Component used by newEntity to track the number of issued entities. --   Automatically added to any world created with @makeWorld@ newtype EntityCounter = EntityCounter {getCounter :: Sum Int} deriving (Monoid, Eq, Show)@@ -57,7 +54,7 @@ -- | Writes the given components to a new entity, and yields that entity. -- The return value is often ignored. {-# INLINE newEntity #-}-newEntity :: (Store (Storage c), Has w c, Has w EntityCounter)+newEntity :: (Set w c, Get w EntityCounter, Set w EntityCounter)           => c -> System w Entity newEntity c = do ety <- nextEntity                  set ety c