{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
module Aztecs.ECS.Query.Reader
(
QueryReader (..),
ArrowQueryReader (..),
ArrowDynamicQueryReader (..),
all,
all',
QueryFilter (..),
with,
without,
DynamicQueryFilter (..),
)
where
import Aztecs.ECS.Component
import Aztecs.ECS.Query.Dynamic (DynamicQueryFilter (..))
import Aztecs.ECS.Query.Dynamic.Reader (DynamicQueryReader (..), allDyn)
import Aztecs.ECS.Query.Dynamic.Reader.Class (ArrowDynamicQueryReader (..))
import Aztecs.ECS.Query.Reader.Class (ArrowQueryReader (..))
import Aztecs.ECS.World.Components (Components)
import qualified Aztecs.ECS.World.Components as CS
import Aztecs.ECS.World.Entities (Entities (..))
import qualified Aztecs.ECS.World.Entities as E
import Control.Arrow (Arrow (..), ArrowChoice (..))
import Control.Category (Category (..))
import Data.Set (Set)
import qualified Data.Set as Set
import Prelude hiding (all, id, (.))
newtype QueryReader i o
= QueryReader {forall i o.
QueryReader i o
-> Components
-> (Set ComponentID, Components, DynamicQueryReader i o)
runQueryReader :: Components -> (Set ComponentID, Components, DynamicQueryReader i o)}
deriving ((forall a b. (a -> b) -> QueryReader i a -> QueryReader i b)
-> (forall a b. a -> QueryReader i b -> QueryReader i a)
-> Functor (QueryReader i)
forall a b. a -> QueryReader i b -> QueryReader i a
forall a b. (a -> b) -> QueryReader i a -> QueryReader i b
forall i a b. a -> QueryReader i b -> QueryReader i a
forall i a b. (a -> b) -> QueryReader i a -> QueryReader i b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall i a b. (a -> b) -> QueryReader i a -> QueryReader i b
fmap :: forall a b. (a -> b) -> QueryReader i a -> QueryReader i b
$c<$ :: forall i a b. a -> QueryReader i b -> QueryReader i a
<$ :: forall a b. a -> QueryReader i b -> QueryReader i a
Functor)
instance Applicative (QueryReader i) where
pure :: forall a. a -> QueryReader i a
pure a
a = (Components
-> (Set ComponentID, Components, DynamicQueryReader i a))
-> QueryReader i a
forall i o.
(Components
-> (Set ComponentID, Components, DynamicQueryReader i o))
-> QueryReader i o
QueryReader ((Components
-> (Set ComponentID, Components, DynamicQueryReader i a))
-> QueryReader i a)
-> (Components
-> (Set ComponentID, Components, DynamicQueryReader i a))
-> QueryReader i a
forall a b. (a -> b) -> a -> b
$ \Components
cs -> (Set ComponentID
forall a. Monoid a => a
mempty, Components
cs, a -> DynamicQueryReader i a
forall a. a -> DynamicQueryReader i a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a)
(QueryReader Components
-> (Set ComponentID, Components, DynamicQueryReader i (a -> b))
f) <*> :: forall a b.
QueryReader i (a -> b) -> QueryReader i a -> QueryReader i b
<*> (QueryReader Components -> (Set ComponentID, Components, DynamicQueryReader i a)
g) = (Components
-> (Set ComponentID, Components, DynamicQueryReader i b))
-> QueryReader i b
forall i o.
(Components
-> (Set ComponentID, Components, DynamicQueryReader i o))
-> QueryReader i o
QueryReader ((Components
-> (Set ComponentID, Components, DynamicQueryReader i b))
-> QueryReader i b)
-> (Components
-> (Set ComponentID, Components, DynamicQueryReader i b))
-> QueryReader i b
forall a b. (a -> b) -> a -> b
$ \Components
cs ->
let (Set ComponentID
cIdsG, Components
cs', DynamicQueryReader i a
aQS) = Components -> (Set ComponentID, Components, DynamicQueryReader i a)
g Components
cs
(Set ComponentID
cIdsF, Components
cs'', DynamicQueryReader i (a -> b)
bQS) = Components
-> (Set ComponentID, Components, DynamicQueryReader i (a -> b))
f Components
cs'
in (Set ComponentID
cIdsG Set ComponentID -> Set ComponentID -> Set ComponentID
forall a. Semigroup a => a -> a -> a
<> Set ComponentID
cIdsF, Components
cs'', DynamicQueryReader i (a -> b)
bQS DynamicQueryReader i (a -> b)
-> DynamicQueryReader i a -> DynamicQueryReader i b
forall a b.
DynamicQueryReader i (a -> b)
-> DynamicQueryReader i a -> DynamicQueryReader i b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> DynamicQueryReader i a
aQS)
instance Category QueryReader where
id :: forall a. QueryReader a a
id = (Components
-> (Set ComponentID, Components, DynamicQueryReader a a))
-> QueryReader a a
forall i o.
(Components
-> (Set ComponentID, Components, DynamicQueryReader i o))
-> QueryReader i o
QueryReader ((Components
-> (Set ComponentID, Components, DynamicQueryReader a a))
-> QueryReader a a)
-> (Components
-> (Set ComponentID, Components, DynamicQueryReader a a))
-> QueryReader a a
forall a b. (a -> b) -> a -> b
$ \Components
cs -> (Set ComponentID
forall a. Monoid a => a
mempty, Components
cs, DynamicQueryReader a a
forall a. DynamicQueryReader a a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id)
(QueryReader Components -> (Set ComponentID, Components, DynamicQueryReader b c)
f) . :: forall b c a. QueryReader b c -> QueryReader a b -> QueryReader a c
. (QueryReader Components -> (Set ComponentID, Components, DynamicQueryReader a b)
g) = (Components
-> (Set ComponentID, Components, DynamicQueryReader a c))
-> QueryReader a c
forall i o.
(Components
-> (Set ComponentID, Components, DynamicQueryReader i o))
-> QueryReader i o
QueryReader ((Components
-> (Set ComponentID, Components, DynamicQueryReader a c))
-> QueryReader a c)
-> (Components
-> (Set ComponentID, Components, DynamicQueryReader a c))
-> QueryReader a c
forall a b. (a -> b) -> a -> b
$ \Components
cs ->
let (Set ComponentID
cIdsG, Components
cs', DynamicQueryReader a b
aQS) = Components -> (Set ComponentID, Components, DynamicQueryReader a b)
g Components
cs
(Set ComponentID
cIdsF, Components
cs'', DynamicQueryReader b c
bQS) = Components -> (Set ComponentID, Components, DynamicQueryReader b c)
f Components
cs'
in (Set ComponentID
cIdsG Set ComponentID -> Set ComponentID -> Set ComponentID
forall a. Semigroup a => a -> a -> a
<> Set ComponentID
cIdsF, Components
cs'', DynamicQueryReader b c
bQS DynamicQueryReader b c
-> DynamicQueryReader a b -> DynamicQueryReader a c
forall b c a.
DynamicQueryReader b c
-> DynamicQueryReader a b -> DynamicQueryReader a c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. DynamicQueryReader a b
aQS)
instance Arrow QueryReader where
arr :: forall b c. (b -> c) -> QueryReader b c
arr b -> c
f = (Components
-> (Set ComponentID, Components, DynamicQueryReader b c))
-> QueryReader b c
forall i o.
(Components
-> (Set ComponentID, Components, DynamicQueryReader i o))
-> QueryReader i o
QueryReader ((Components
-> (Set ComponentID, Components, DynamicQueryReader b c))
-> QueryReader b c)
-> (Components
-> (Set ComponentID, Components, DynamicQueryReader b c))
-> QueryReader b c
forall a b. (a -> b) -> a -> b
$ \Components
cs -> (Set ComponentID
forall a. Monoid a => a
mempty, Components
cs, (b -> c) -> DynamicQueryReader b c
forall b c. (b -> c) -> DynamicQueryReader b c
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr b -> c
f)
first :: forall b c d. QueryReader b c -> QueryReader (b, d) (c, d)
first (QueryReader Components -> (Set ComponentID, Components, DynamicQueryReader b c)
f) = (Components
-> (Set ComponentID, Components, DynamicQueryReader (b, d) (c, d)))
-> QueryReader (b, d) (c, d)
forall i o.
(Components
-> (Set ComponentID, Components, DynamicQueryReader i o))
-> QueryReader i o
QueryReader ((Components
-> (Set ComponentID, Components, DynamicQueryReader (b, d) (c, d)))
-> QueryReader (b, d) (c, d))
-> (Components
-> (Set ComponentID, Components, DynamicQueryReader (b, d) (c, d)))
-> QueryReader (b, d) (c, d)
forall a b. (a -> b) -> a -> b
$ \Components
comps -> let (Set ComponentID
cIds, Components
comps', DynamicQueryReader b c
qS) = Components -> (Set ComponentID, Components, DynamicQueryReader b c)
f Components
comps in (Set ComponentID
cIds, Components
comps', DynamicQueryReader b c -> DynamicQueryReader (b, d) (c, d)
forall b c d.
DynamicQueryReader b c -> DynamicQueryReader (b, d) (c, d)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first DynamicQueryReader b c
qS)
instance ArrowChoice QueryReader where
left :: forall b c d.
QueryReader b c -> QueryReader (Either b d) (Either c d)
left (QueryReader Components -> (Set ComponentID, Components, DynamicQueryReader b c)
f) = (Components
-> (Set ComponentID, Components,
DynamicQueryReader (Either b d) (Either c d)))
-> QueryReader (Either b d) (Either c d)
forall i o.
(Components
-> (Set ComponentID, Components, DynamicQueryReader i o))
-> QueryReader i o
QueryReader ((Components
-> (Set ComponentID, Components,
DynamicQueryReader (Either b d) (Either c d)))
-> QueryReader (Either b d) (Either c d))
-> (Components
-> (Set ComponentID, Components,
DynamicQueryReader (Either b d) (Either c d)))
-> QueryReader (Either b d) (Either c d)
forall a b. (a -> b) -> a -> b
$ \Components
comps -> let (Set ComponentID
cIds, Components
comps', DynamicQueryReader b c
qS) = Components -> (Set ComponentID, Components, DynamicQueryReader b c)
f Components
comps in (Set ComponentID
cIds, Components
comps', DynamicQueryReader b c
-> DynamicQueryReader (Either b d) (Either c d)
forall b c d.
DynamicQueryReader b c
-> DynamicQueryReader (Either b d) (Either c d)
forall (a :: * -> * -> *) b c d.
ArrowChoice a =>
a b c -> a (Either b d) (Either c d)
left DynamicQueryReader b c
qS)
instance ArrowQueryReader QueryReader where
fetch :: forall a. (Component a) => QueryReader () a
fetch :: forall a. Component a => QueryReader () a
fetch = (Components
-> (Set ComponentID, Components, DynamicQueryReader () a))
-> QueryReader () a
forall i o.
(Components
-> (Set ComponentID, Components, DynamicQueryReader i o))
-> QueryReader i o
QueryReader ((Components
-> (Set ComponentID, Components, DynamicQueryReader () a))
-> QueryReader () a)
-> (Components
-> (Set ComponentID, Components, DynamicQueryReader () a))
-> QueryReader () a
forall a b. (a -> b) -> a -> b
$ \Components
cs ->
let (ComponentID
cId, Components
cs') = forall a. Component a => Components -> (ComponentID, Components)
CS.insert @a Components
cs in (ComponentID -> Set ComponentID
forall a. a -> Set a
Set.singleton ComponentID
cId, Components
cs', ComponentID -> DynamicQueryReader () a
forall a. Component a => ComponentID -> DynamicQueryReader () a
forall (arr :: * -> * -> *) a.
(ArrowDynamicQueryReader arr, Component a) =>
ComponentID -> arr () a
fetchDyn ComponentID
cId)
fetchMaybe :: forall a. (Component a) => QueryReader () (Maybe a)
fetchMaybe :: forall a. Component a => QueryReader () (Maybe a)
fetchMaybe = (Components
-> (Set ComponentID, Components, DynamicQueryReader () (Maybe a)))
-> QueryReader () (Maybe a)
forall i o.
(Components
-> (Set ComponentID, Components, DynamicQueryReader i o))
-> QueryReader i o
QueryReader ((Components
-> (Set ComponentID, Components, DynamicQueryReader () (Maybe a)))
-> QueryReader () (Maybe a))
-> (Components
-> (Set ComponentID, Components, DynamicQueryReader () (Maybe a)))
-> QueryReader () (Maybe a)
forall a b. (a -> b) -> a -> b
$ \Components
cs ->
let (ComponentID
cId, Components
cs') = forall a. Component a => Components -> (ComponentID, Components)
CS.insert @a Components
cs in (ComponentID -> Set ComponentID
forall a. a -> Set a
Set.singleton ComponentID
cId, Components
cs', ComponentID -> DynamicQueryReader () (Maybe a)
forall a.
Component a =>
ComponentID -> DynamicQueryReader () (Maybe a)
forall (arr :: * -> * -> *) a.
(ArrowDynamicQueryReader arr, Component a) =>
ComponentID -> arr () (Maybe a)
fetchMaybeDyn ComponentID
cId)
instance ArrowDynamicQueryReader QueryReader where
entity :: QueryReader () EntityID
entity = (Components
-> (Set ComponentID, Components, DynamicQueryReader () EntityID))
-> QueryReader () EntityID
forall i o.
(Components
-> (Set ComponentID, Components, DynamicQueryReader i o))
-> QueryReader i o
QueryReader ((Components
-> (Set ComponentID, Components, DynamicQueryReader () EntityID))
-> QueryReader () EntityID)
-> (Components
-> (Set ComponentID, Components, DynamicQueryReader () EntityID))
-> QueryReader () EntityID
forall a b. (a -> b) -> a -> b
$ \Components
cs -> (Set ComponentID
forall a. Monoid a => a
mempty, Components
cs, DynamicQueryReader () EntityID
forall (arr :: * -> * -> *).
ArrowDynamicQueryReader arr =>
arr () EntityID
entity)
fetchDyn :: forall a. Component a => ComponentID -> QueryReader () a
fetchDyn ComponentID
cId = (Components
-> (Set ComponentID, Components, DynamicQueryReader () a))
-> QueryReader () a
forall i o.
(Components
-> (Set ComponentID, Components, DynamicQueryReader i o))
-> QueryReader i o
QueryReader ((Components
-> (Set ComponentID, Components, DynamicQueryReader () a))
-> QueryReader () a)
-> (Components
-> (Set ComponentID, Components, DynamicQueryReader () a))
-> QueryReader () a
forall a b. (a -> b) -> a -> b
$ \Components
cs -> (ComponentID -> Set ComponentID
forall a. a -> Set a
Set.singleton ComponentID
cId, Components
cs, ComponentID -> DynamicQueryReader () a
forall a. Component a => ComponentID -> DynamicQueryReader () a
forall (arr :: * -> * -> *) a.
(ArrowDynamicQueryReader arr, Component a) =>
ComponentID -> arr () a
fetchDyn ComponentID
cId)
fetchMaybeDyn :: forall a. Component a => ComponentID -> QueryReader () (Maybe a)
fetchMaybeDyn ComponentID
cId = (Components
-> (Set ComponentID, Components, DynamicQueryReader () (Maybe a)))
-> QueryReader () (Maybe a)
forall i o.
(Components
-> (Set ComponentID, Components, DynamicQueryReader i o))
-> QueryReader i o
QueryReader ((Components
-> (Set ComponentID, Components, DynamicQueryReader () (Maybe a)))
-> QueryReader () (Maybe a))
-> (Components
-> (Set ComponentID, Components, DynamicQueryReader () (Maybe a)))
-> QueryReader () (Maybe a)
forall a b. (a -> b) -> a -> b
$ \Components
cs -> (ComponentID -> Set ComponentID
forall a. a -> Set a
Set.singleton ComponentID
cId, Components
cs, ComponentID -> DynamicQueryReader () (Maybe a)
forall a.
Component a =>
ComponentID -> DynamicQueryReader () (Maybe a)
forall (arr :: * -> * -> *) a.
(ArrowDynamicQueryReader arr, Component a) =>
ComponentID -> arr () (Maybe a)
fetchMaybeDyn ComponentID
cId)
newtype QueryFilter = QueryFilter {QueryFilter -> Components -> (DynamicQueryFilter, Components)
runQueryFilter :: Components -> (DynamicQueryFilter, Components)}
instance Semigroup QueryFilter where
QueryFilter
a <> :: QueryFilter -> QueryFilter -> QueryFilter
<> QueryFilter
b =
(Components -> (DynamicQueryFilter, Components)) -> QueryFilter
QueryFilter
( \Components
cs ->
let (DynamicQueryFilter
withA', Components
cs') = QueryFilter -> Components -> (DynamicQueryFilter, Components)
runQueryFilter QueryFilter
a Components
cs
(DynamicQueryFilter
withB', Components
cs'') = QueryFilter -> Components -> (DynamicQueryFilter, Components)
runQueryFilter QueryFilter
b Components
cs'
in (DynamicQueryFilter
withA' DynamicQueryFilter -> DynamicQueryFilter -> DynamicQueryFilter
forall a. Semigroup a => a -> a -> a
<> DynamicQueryFilter
withB', Components
cs'')
)
instance Monoid QueryFilter where
mempty :: QueryFilter
mempty = (Components -> (DynamicQueryFilter, Components)) -> QueryFilter
QueryFilter (DynamicQueryFilter
forall a. Monoid a => a
mempty,)
with :: forall a. (Component a) => QueryFilter
with :: forall a. Component a => QueryFilter
with = (Components -> (DynamicQueryFilter, Components)) -> QueryFilter
QueryFilter ((Components -> (DynamicQueryFilter, Components)) -> QueryFilter)
-> (Components -> (DynamicQueryFilter, Components)) -> QueryFilter
forall a b. (a -> b) -> a -> b
$ \Components
cs ->
let (ComponentID
cId, Components
cs') = forall a. Component a => Components -> (ComponentID, Components)
CS.insert @a Components
cs in (DynamicQueryFilter
forall a. Monoid a => a
mempty {filterWith = Set.singleton cId}, Components
cs')
without :: forall a. (Component a) => QueryFilter
without :: forall a. Component a => QueryFilter
without = (Components -> (DynamicQueryFilter, Components)) -> QueryFilter
QueryFilter ((Components -> (DynamicQueryFilter, Components)) -> QueryFilter)
-> (Components -> (DynamicQueryFilter, Components)) -> QueryFilter
forall a b. (a -> b) -> a -> b
$ \Components
cs ->
let (ComponentID
cId, Components
cs') = forall a. Component a => Components -> (ComponentID, Components)
CS.insert @a Components
cs in (DynamicQueryFilter
forall a. Monoid a => a
mempty {filterWithout = Set.singleton cId}, Components
cs')
all :: i -> QueryReader i a -> Entities -> ([a], Entities)
all :: forall i a. i -> QueryReader i a -> Entities -> ([a], Entities)
all i
i QueryReader i a
q Entities
es = let ([a]
as, Components
cs) = i -> QueryReader i a -> Entities -> ([a], Components)
forall i a. i -> QueryReader i a -> Entities -> ([a], Components)
all' i
i QueryReader i a
q Entities
es in ([a]
as, Entities
es {E.components = cs})
all' :: i -> QueryReader i a -> Entities -> ([a], Components)
all' :: forall i a. i -> QueryReader i a -> Entities -> ([a], Components)
all' i
i QueryReader i a
q Entities
es = let (Set ComponentID
rs, Components
cs', DynamicQueryReader i a
dynQ) = QueryReader i a
-> Components
-> (Set ComponentID, Components, DynamicQueryReader i a)
forall i o.
QueryReader i o
-> Components
-> (Set ComponentID, Components, DynamicQueryReader i o)
runQueryReader QueryReader i a
q (Entities -> Components
E.components Entities
es) in (Set ComponentID -> i -> DynamicQueryReader i a -> Entities -> [a]
forall i a.
Set ComponentID -> i -> DynamicQueryReader i a -> Entities -> [a]
allDyn Set ComponentID
rs i
i DynamicQueryReader i a
dynQ Entities
es, Components
cs')