apecs 0.2.4.4 → 0.2.4.5
raw patch · 12 files changed
+110/−83 lines, 12 filesPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
API changes (from Hackage documentation)
+ Apecs: getUnsafe :: forall w c. Has w c => Entity c -> System w c
+ Apecs.System: getUnsafe :: forall w c. Has w c => Entity c -> System w c
Files
- README.md +1/−0
- apecs.cabal +1/−1
- src/Apecs.hs +9/−10
- src/Apecs/Concurrent.hs +8/−6
- src/Apecs/Logs.hs +21/−15
- src/Apecs/Slice.hs +8/−6
- src/Apecs/Stores.hs +18/−16
- src/Apecs/System.hs +16/−6
- src/Apecs/TH.hs +2/−2
- src/Apecs/THTuples.hs +1/−1
- src/Apecs/Types.hs +11/−10
- src/Apecs/Util.hs +14/−10
README.md view
@@ -5,6 +5,7 @@ It exposes a DSL that translates to fast storage operations, resulting in expressivity without sacrificing performance or safety. There is an example below, and a tutorial can be found [here](https://github.com/jonascarpay/apecs/blob/master/tutorials/RTS.md).+For a physics engine written on top of apecs, check out [phycs](https://github.com/jonascarpay/phycs). For a general introduction to ECS, see [this talk](https://www.youtube.com/watch?v=lNTaC-JWmdI&feature=youtu.be&t=218) or [here](https://en.wikipedia.org/wiki/Entity–component–system). ### Performance
apecs.cabal view
@@ -1,5 +1,5 @@ name: apecs-version: 0.2.4.4+version: 0.2.4.5 homepage: https://github.com/jonascarpay/apecs#readme license: BSD3 license-file: LICENSE
src/Apecs.hs view
@@ -8,15 +8,13 @@ Component(..), Entity(..), Slice, Has(..), Safe(..), cast, Map, Set, Unique, Global, Flag(..), - -- * Store wrapper functions initStore, destroy, exists, owners, resetStore,- get, set, set', modify,+ get, getUnsafe, set, set', modify, cmap, cmapM, cmapM_, cimapM, cimapM_, rmap', rmap, wmap, wmap', cmap', - -- ** GlobalRW wrapper functions getGlobal, setGlobal, modifyGlobal, @@ -24,15 +22,16 @@ runSystem, runWith, runGC, EntityCounter, newEntity, makeWorld,- -- Reader++ -- * Re-exports asks, ask, liftIO, lift, ) where -import Control.Monad.Reader (asks, ask, liftIO, lift)+import Control.Monad.Reader (ask, asks, lift, liftIO) -import Apecs.Types-import Apecs.System-import Apecs.Stores-import Apecs.Util-import Apecs.TH+import Apecs.Stores+import Apecs.System+import Apecs.TH+import Apecs.Types+import Apecs.Util
src/Apecs/Concurrent.hs view
@@ -1,5 +1,7 @@-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE FlexibleContexts, FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-} module Apecs.Concurrent ( concurrently,@@ -7,11 +9,11 @@ ) where import qualified Control.Concurrent.Async as A-import Control.Monad.Reader-import qualified Data.Vector.Unboxed as U+import Control.Monad.Reader+import qualified Data.Vector.Unboxed as U -import Apecs.Types-import Apecs.System+import Apecs.System+import Apecs.Types -- | 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.
src/Apecs/Logs.hs view
@@ -1,8 +1,14 @@-{-# LANGUAGE TypeFamilies, MultiParamTypeClasses, ConstraintKinds #-}-{-# LANGUAGE ScopedTypeVariables, FlexibleInstances, FlexibleContexts #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE Strict #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE Strict #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-} +-- | Experimental module for logging a store+ module Apecs.Logs ( -- * Types and classes Log(..), PureLog(..), FromPure(..), Logger, getLog, readIORef,@@ -12,14 +18,14 @@ EnumTable, byIndex, byEnum, ) where -import Data.IORef-import qualified Data.Vector.Mutable as VM-import qualified Data.IntSet as S-import Control.Monad.Reader+import Control.Monad.Reader+import qualified Data.IntSet as S+import Data.IORef+import qualified Data.Vector.Mutable as VM -import Apecs.Types-import Apecs.Stores-import qualified Apecs.Slice as Sl+import qualified Apecs.Slice as Sl+import Apecs.Stores+import Apecs.Types -- | A PureLog is a piece of state @l c@ that is updated when components @c@ are written or destroyed. -- Note that @l :: * -> *@@@ -73,7 +79,7 @@ mc <- explGet s ety case mc of Just c -> logOnDestroy l (Entity ety) c >> explDestroy s ety- _ -> return ()+ _ -> return () {-# INLINE explExists #-} explExists (Logger _ s) ety = explExists s ety@@ -100,13 +106,13 @@ {-# INLINE explSetMaybe #-} explSetMaybe s ety (Nothing) = explDestroy s ety- explSetMaybe s ety (Just x) = explSet s ety x+ explSetMaybe s ety (Just x) = explSet s ety x {-# INLINE explModify #-} explModify (Logger l s) ety f = do mc <- explGet s ety case mc of- Just c -> explSet (Logger l s) ety (f c)+ Just c -> explSet (Logger l s) ety (f c) Nothing -> return () {-# INLINE explCmapM_ #-}@@ -179,7 +185,7 @@ logOnSet (EnumTable vec) (Entity e) old new = do case old of Nothing -> return ()- Just c -> VM.modify vec (S.delete e) (fromEnum c)+ Just c -> VM.modify vec (S.delete e) (fromEnum c) VM.modify vec (S.insert e) (fromEnum new) {-# INLINE logOnDestroy #-}
src/Apecs/Slice.hs view
@@ -1,14 +1,16 @@-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE FlexibleContexts, FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-} -- | This module is designed to be imported with qualified module Apecs.Slice where -import qualified Data.Vector.Unboxed as U-import Data.Traversable (for)-import Control.Monad.IO.Class+import Control.Monad.Reader (liftIO)+import Data.Traversable (for)+import qualified Data.Vector.Unboxed as U -import Apecs.Types+import Apecs.Types -- | Slice version of foldM_ {-# INLINE foldM_ #-}
src/Apecs/Stores.hs view
@@ -1,10 +1,12 @@-{-# LANGUAGE Strict #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE KindSignatures #-} {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE FlexibleContexts, FlexibleInstances #-}-{-# LANGUAGE DataKinds, KindSignatures #-}-{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE Strict #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-} module Apecs.Stores ( Map, Set, Flag(..), Cache, Unique,@@ -12,18 +14,18 @@ Cachable, ) where -import qualified Data.IntMap.Strict as M-import qualified Data.IntSet as S-import Data.IORef-import Data.Maybe (fromJust)-import qualified Data.Vector.Unboxed as U+import Control.Monad.Reader+import qualified Data.IntMap.Strict as M+import qualified Data.IntSet as S+import Data.IORef+import Data.Maybe (fromJust)+import Data.Proxy+import qualified Data.Vector.Mutable as VM+import qualified Data.Vector.Unboxed as U import qualified Data.Vector.Unboxed.Mutable as UM-import qualified Data.Vector.Mutable as VM-import Control.Monad.Reader-import GHC.TypeLits-import Data.Proxy+import GHC.TypeLits -import Apecs.Types+import Apecs.Types {-# INLINE defaultSetMaybe #-} defaultSetMaybe :: (Store s, SafeRW s ~ Maybe (Stores s)) => s -> Int -> Maybe (Stores s) -> IO ()
src/Apecs/System.hs view
@@ -1,13 +1,15 @@-{-# LANGUAGE Strict #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE Strict #-} module Apecs.System where -import Control.Monad.Reader-import qualified Data.Vector.Unboxed as U+import Control.Monad.Reader+import qualified Data.Vector.Unboxed as U -import Apecs.Types+import Apecs.Types -- | Run a system with a game world {-# INLINE runSystem #-}@@ -53,7 +55,15 @@ get (Entity ety) = do s :: Storage c <- getStore liftIO$ Safe <$> explGet s ety +-- | Same as @get@, but does not return a safe value and therefore errors if the target component is not present.+{-# INLINE getUnsafe #-}+getUnsafe :: forall w c. Has w c => Entity c -> System w c+getUnsafe (Entity ety) = do s :: Storage c <- getStore+ liftIO$ explGetUnsafe s ety+ -- | 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' {-# INLINE set #-} set :: forall w c e. Has w c => Entity e -> c -> System w () set (Entity ety) x = do
src/Apecs/TH.hs view
@@ -4,9 +4,9 @@ ( makeWorld, makeWorldNoEC )where -import Language.Haskell.TH+import Language.Haskell.TH -import Apecs.Util (EntityCounter)+import Apecs.Util (EntityCounter) genName :: String -> Q Name genName s = mkName . show <$> newName s
src/Apecs/THTuples.hs view
@@ -2,8 +2,8 @@ module Apecs.THTuples where -import Language.Haskell.TH import qualified Data.Vector.Unboxed as U+import Language.Haskell.TH -- | Generate tuple instances for the following tuple sizes. makeInstances :: [Int] -> Q [Dec]
src/Apecs/Types.hs view
@@ -1,18 +1,19 @@-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE FlexibleContexts, FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-} module Apecs.Types where -import Control.Monad.Reader-import Data.Traversable (for)-import qualified Data.Vector.Unboxed as U+import Control.Monad.Reader+import Data.Traversable (for)+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. The type variable is used to keep track of reads and writes, but can be freely cast. newtype Entity c = Entity {unEntity :: Int} deriving (Eq, Ord, Show)
src/Apecs/Util.hs view
@@ -1,6 +1,10 @@-{-# LANGUAGE Strict, ScopedTypeVariables, TypeFamilies #-}-{-# LANGUAGE MultiParamTypeClasses, FlexibleContexts, FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE Strict #-}+{-# LANGUAGE TypeFamilies #-} module Apecs.Util ( -- * Utility@@ -22,15 +26,15 @@ ) where -import System.Mem (performMajorGC)-import Control.Monad.Reader (liftIO)-import Control.Applicative (liftA2)-import System.CPUTime-import Data.Monoid+import Control.Applicative (liftA2)+import Control.Monad.Reader (liftIO)+import Data.Monoid+import System.CPUTime+import System.Mem (performMajorGC) -import Apecs.Types-import Apecs.Stores-import Apecs.System+import Apecs.Stores+import Apecs.System+import Apecs.Types -- | A proxy entity for TODO proxy :: Entity c