apecs 0.2.1.0 → 0.2.1.1
raw patch · 6 files changed
+56/−39 lines, 6 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Apecs: class Flag c
+ Apecs: data EntityCounter
+ Apecs: flag :: Flag c => c
+ Apecs: initCounter :: IO (Storage EntityCounter)
+ Apecs: initStore :: (Initializable s, InitArgs s ~ ()) => IO s
+ Apecs: newEntity :: (IsRuntime c, Has w c, Has w EntityCounter) => c -> System w (Entity c)
+ Apecs: runGC :: System w ()
+ Apecs.Logs: readIORef :: IORef a -> IO a
+ Apecs.Util: unsafeFlatten :: (Applicative v, Integral a, Foldable v) => v a -> v a -> a
- Apecs.Util: flatten :: (Applicative v, Integral a, Foldable v) => v a -> v a -> a
+ Apecs.Util: flatten :: (Applicative v, Integral a, Foldable v) => v a -> v a -> Maybe a
- Apecs.Util: inbounds :: (Num (v a), Ord a, Applicative v, Foldable v) => v a -> v a -> Bool
+ Apecs.Util: inbounds :: (Num a, Ord a, Applicative v, Foldable v) => v a -> v a -> Bool
Files
- README.md +6/−6
- apecs.cabal +1/−1
- src/Apecs.hs +10/−6
- src/Apecs/Logs.hs +2/−2
- src/Apecs/Util.hs +32/−19
- test/Main.hs +5/−5
README.md view
@@ -11,16 +11,15 @@ Performance is good. Running the [ecs-bench](https://github.com/lschmierer/ecs_bench) pos_vel benchmark shows that we can keep up with specs, which was written in Rust: -| | specs | apecs |-| --- | ----- | --- |-| build | 699 us | 285 us | -| update | 34 us | 46 us |+| | specs | apecs |+| ------ | ------ | ------ |+| build | 699 us | 285 us | +| update | 34 us | 46 us | ### Example ```haskell import Apecs-import Apecs.Stores-import Apecs.Util+import Apecs.Stores (Cache) import Linear -- Component data definitions@@ -79,4 +78,5 @@ main :: IO () main = do w <- World <$> initStore <*> initStore <*> initStore <*> initCounter runSystem game w+ ```
apecs.cabal view
@@ -1,5 +1,5 @@ name: apecs-version: 0.2.1.0+version: 0.2.1.1 homepage: https://github.com/jonascarpay/apecs#readme license: BSD3 license-file: LICENSE
src/Apecs.hs view
@@ -1,29 +1,32 @@-{-# LANGUAGE FlexibleContexts #-}-+{-|+This module forms the apecs Prelude.+It selectively re-exports the user-facing functions from the submodules.+-} module Apecs ( -- * Types System(..), Component(..), Entity(..), Slice, Has(..), Safe(..), cast,- Map, Set, Unique, Global,+ Map, Set, Unique, Global, Flag(..), -- * Initializable initStoreWith, - -- * HasMembers wrapper functions+ -- ** HasMembers wrapper functions destroy, exists, owners, resetStore, - -- * Store wrapper functions+ -- ** Store wrapper functions get, set, set', modify, cmap, cmapM, cmapM_, cimapM, cimapM_, rmap', rmap, wmap, wmap', cmap', - -- * GlobalRW wrapper functions+ -- ** GlobalRW wrapper functions readGlobal, writeGlobal, modifyGlobal, -- * Other runSystem, runWith,+ initStore, runGC, EntityCounter, initCounter, newEntity, -- All slice functions module SL,@@ -38,4 +41,5 @@ import Apecs.System import Apecs.Slice as SL import Apecs.Stores+import Apecs.Util
src/Apecs/Logs.hs view
@@ -6,7 +6,7 @@ module Apecs.Logs ( -- * Types and classes- Log(..), PureLog(..), FromPure(..), Logger, getLog,+ Log(..), PureLog(..), FromPure(..), Logger, getLog, readIORef, LVec1, LVec2, LVec3, -- * EnumTable@@ -202,6 +202,6 @@ | otherwise = liftIO$ sliceFromList . S.toList <$> VM.read vec c -- | Query the @EnumTable@ by an example enum.--- Will not perform bound checks, so crashes if @fromEnum c < 0 && fromEnum c > fromEnum maxBound @.+-- Will not perform bound checks, so crashes if `fromEnum c < 0 && fromEnum c > fromEnum maxBound `. byEnum :: Enum c => EnumTable c -> c -> System w (Slice c) byEnum (EnumTable vec) c = liftIO$ sliceFromList . S.toList <$> VM.read vec (fromEnum c)
src/Apecs/Util.hs view
@@ -11,7 +11,7 @@ -- * Spatial hashing -- $hash- quantize, flatten, region, inbounds,+ quantize, flatten, inbounds, region, unsafeFlatten, -- * Timing timeSystem, timeSystem_,@@ -65,15 +65,20 @@ -- $hash -- The following functions are for spatial hashing. -- The idea is that your spatial hash is defined by two vectors;+-- -- - The cell size vector contains real components and dictates--- how large each cell in your table is spatially.--- It is used to translate from world-space to table space--- - The field size vector contains integral components and dictates how+-- how large each cell in your table is in world space units.+-- It is used by @quantize@ to translate a world space coordinate into a table space index vector+-- - The table size vector contains integral components and dictates how -- many cells your field consists of in each direction.--- It is used to translate from table-space to a flat integer+-- It is used by @flatten@ to translate a table-space index vector into a flat integer+--+-- There is currently no dedicated spatial hashing log, but you can use+-- an EnumTable by defining an instance Enum Vec with+-- > fromEnum = flatten size . quantize cell -- | Quantize turns a world-space coordinate into a table-space coordinate by dividing--- by the given cell size and round components towards negative infinity+-- by the given cell size and rounding towards negative infinity. {-# INLINE quantize #-} quantize :: (Fractional (v a), Integral b, RealFrac a, Functor v) => v a -- ^ Quantization cell size@@ -81,6 +86,21 @@ -> v b quantize cell vec = floor <$> vec/cell +-- | Turns a table-space vector into an integral index, given some table size vector.+-- Yields Nothing for out-of-bounds queries+{-# INLINE flatten #-}+flatten :: (Applicative v, Integral a, Foldable v)+ => v a -- Field size vector+ -> v a -> Maybe a+flatten size vec = if inbounds size vec then Just (unsafeFlatten size vec) else Nothing++-- | Tests whether a vector is in the region given by 0 and the size vector (inclusive)+{-# INLINE inbounds #-}+inbounds :: (Num a, Ord a, Applicative v, Foldable v)+ => v a -- Field size vector+ -> v a -> Bool+inbounds size vec = and (liftA2 (\v s -> v >= 0 && v <= s) vec size)+ -- | 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. {-# INLINE region #-}@@ -90,19 +110,12 @@ -> [v a] region a b = sequence $ liftA2 enumFromTo a b --- | Turns a table-space vector into a linear index, given some table size vector.-{-# INLINE flatten #-}-flatten :: (Applicative v, Integral a, Foldable v)- => v a -- Field size vector- -> v a -> a-flatten size vec = foldr (\(n,x) acc -> n*acc + x) 0 (liftA2 (,) size vec)---- | Tests whether a vector is in the region given by 0 and the size vector-{-# INLINE inbounds #-}-inbounds :: (Num (v a), Ord a, Applicative v, Foldable v)- => v a -> v a -> Bool-inbounds size vec = and (liftA2 (>=) vec 0) && and (liftA2 (<=) vec size)-+-- | Unsafe version of flatten. Yields garbage for out-of-bounds queries.+{-# INLINE unsafeFlatten #-}+unsafeFlatten :: (Applicative v, Integral a, Foldable v)+ => v a -- Field size vector+ -> v a -> a+unsafeFlatten size vec = foldr (\(n,x) acc -> n*acc + x) 0 (liftA2 (,) size vec) -- | Runs a system and gives its execution time in seconds {-# INLINE timeSystem #-}
test/Main.hs view
@@ -36,11 +36,11 @@ type Storage Velocity = S.Map Velocity -data Flag = Flag-instance Arbitrary Flag where arbitrary = return Flag-instance S.Flag Flag where flag = Flag-instance Component Flag where- type Storage Flag = S.Set Flag+data TestFlag = TestFlag+instance Arbitrary TestFlag where arbitrary = return TestFlag+instance S.Flag TestFlag where flag = TestFlag+instance Component TestFlag where+ type Storage TestFlag = S.Set TestFlag newtype Members c = Members S.IntSet