mischief-ecs
Safe HaskellNone
LanguageGHC2024

Mischief.ECS.World.Query.Pipe

Synopsis

Impure

qtraverse :: (Entity -> a -> m b) -> Query m a -> Query m b Source #

Map Query m a to Query m b with side effects.

Example

[q|Name, Position|]
  & qtraverse (\e (name, pos) -> do
    [i|The name of entity #{e} is #{name}|]
    pure pos
  )
  & query

qtap :: (Entity -> a -> m b) -> Query m a -> Query m a Source #

Apply a side effect over a query.

Example

[q|Name, Position|]
  & qtraverse (\e (name, pos) -> do
    [i|The name of entity #{e} is #{name}|]
  )
  & query

Chaining

qthen :: forall w (m :: Type -> Type) a b. MonadSystem w m => (a -> Query m b) -> Query m a -> Query m b Source #

Folds

qfoldr :: forall w (m :: Type -> Type) a b. MonadSystem w m => (From a -> b -> b) -> b -> Entity -> Query m a -> Query m b Source #

qcollect :: forall w (m :: Type -> Type) a. MonadSystem w m => Entity -> Query m a -> Query m [From a] Source #

Mapping

qmap :: forall w (m :: Type -> Type) a b. MonadSystem w m => (a -> b) -> Query m a -> Query m b Source #

Maps Query m a to Query m b. Same as fmap.

Example

[q|Name, Position|]
  & qmap (\(name, _) -> name)
  & query

qmapM :: MonadSystem w m => (Entity -> a -> m b) -> Query m a -> Query m b Source #

Same as qtraverse.

qmapMaybe :: forall w (m :: Type -> Type) a b. MonadSystem w m => (a -> Maybe b) -> Query m a -> Query m b Source #

Possibly maps each element from Query m a to an element from Query m b. If Nothing, will filter this Entity out of the Query.

Example

f :: Name -> Maybe Name
[q|Name|]
  & qmapMaybe f
  & query

qmapMaybeM :: MonadSystem w m => (Entity -> a -> m (Maybe b)) -> Query m a -> Query m b Source #

Filtering

qcheck :: forall w (m :: Type -> Type) a. MonadSystem w m => QueryFilter 'EntityFilter -> Query m a -> Query m a Source #

Filter the entities of a query with a dedicated query filter.

Example

[q|Position|]
  & qcheck [f|Changed Position, !Added Position|]
  & query

qfilter :: forall w (m :: Type -> Type) a. MonadSystem w m => (a -> Bool) -> Query m a -> Query m a Source #

Filter the entities of a query.

Example

[q|Name|]
  & qfilter (== Name Florian)
  & query

qfilterM :: (Entity -> a -> m Bool) -> Query m a -> Query m a Source #

Filter the entities of a query with possible side effects.

Example

[q|Position|]
  & qfilterM (\e _ -> changed @Position e)
  & query

Insertion

qinsert :: Bundle b => (a -> b) -> Query System a -> Query System a Source #

Insert the values obtained from a mapping function.

Example

q[|Position, Velocity|]
  & qinsert (\(Position p, Velocity v) -> Position (p + v))
  & query

qinsertNew :: Bundle b => (a -> b) -> Query System a -> Query System a Source #

Same as qinsert but only inserts components that aren't already on the entity.

qinsertIfNeq :: BundleEq b => (a -> b) -> Query System a -> Query System a Source #

Same as qinsert but only inserts components that are new or different than the ones already on the entity. Avoids triggering false change detection.

qmodify :: Bundle b => (a -> b) -> Query System a -> Query System b Source #

Same as qinsert but will also propagate the mapped elements. Equivalent to qinsert id . qmap f.

qmodifyNew :: Bundle b => (a -> b) -> Query System a -> Query System b Source #

Same as qinsertNew but will also propagate the mapped elements. Equivalent to qinsertNew id . qmap f.

qmodifyIfNeq :: BundleEq b => (a -> b) -> Query System a -> Query System b Source #

Same as qinsertIfNeq but will also propagate the mapped elements. Equivalent to qinsertIfNeq id . qmap f.

Expansion

qextend :: forall w (m :: Type -> Type) qd out a c. (MonadSystem w m, Queryable qd out) => qd -> (a -> out -> c) -> Query m a -> Query m c Source #

Grab a specific entity from another query and map it into the current one. If the first function returns Nothing, will filter this entity out of the query.

Example

data Sprite = Sprite {image :: Entity} deriving (Component)
[q|Sprite|]
  qget (\sprite -> sprite.image) (,) [q|Image|]
  & query

qget :: (MonadSystem w m) => (a -> Maybe Entity) -> Query m b -> Query m a -> Join m a Maybe (From b) qget f b a = Join a ( _ x -> do let entity = f x case entity of Nothing -> pure Nothing Just entity -> do bs <- get entity b pure $ fmap (From entity) bs )

Grab specific entities from another query. If the first function returns an empty list, will filter this entity out of the query.

Example

data Images = Images {images :: [Entity]} deriving (Component)
[q|Images|]
  & qgetMany (.images) (,) [q|Image|]
  & query

qgetMany :: (MonadSystem w m) => (a -> [Entity]) -> Query m b -> Query m a -> Join m a List (From b) qgetMany f b a = Join a ( _ x -> do let entities = f x y catMaybes <$ mapM (e -> fmap (e,) $ single (mkGet e b)) entities pure $ map (uncurry From) y )

Like qgetMany but with side-effects in the function which provides the entities. qgetManyM :: (MonadSystem w m) => (a -> m [Entity]) -> Query m b -> Query m a -> Join m a List (From b) qgetManyM f b a = Join a ( _ x -> do entities <- f x y catMaybes <$ mapM (e -> fmap (e,) $ single (mkGet e b)) entities pure $ map (uncurry From) y )

Very similar to qappendOneM. This is a helper function mainly intended to make relationship traversals easier.

Example

import Mischief.ECS.Relationships.Graph
[q|Name|]
  & qrelateOne (Graph.outgoing @ChildOf) (,) [q|Name|]
  & qinfo (\(child, parent) -> [i|#{child} is child of #{parent}|])
  & query_

qrelate :: (MonadSystem w m) => (Entity -> m (Maybe Entity)) -> Query m b -> Query m a -> Join m a Maybe (From b) qrelate f b a = Join a ( e _ -> do entity <- f e case entity of Nothing -> pure Nothing Just entity -> do y <- single (mkGet entity b) pure $ fmap (From entity) y )

Very similar to qappendManyM. This is a helper function mainly intended to make relationship traversals easier.

Example

import Mischief.ECS.Relationships.Graph
[q|Name|]
  & qrelateOne (Graph.ingoing @ChildOf) (,) [q|Name|]
  & qinfo (\(parent, children) -> [i|#{parent} is parent of #{children}|])
  & query_

qrelateMany :: (MonadSystem w m) => (Entity -> m [Entity]) -> Query m b -> Query m a -> Join m a List (From b) qrelateMany f b a = Join a ( e _ -> do entities <- f e y catMaybes <$ mapM (e -> fmap (e,) $ single (mkGet e b)) (toList entities) pure $ map (uncurry From) y )

Grab the elements from another query that meet a certain condition in relation to this query. Map them together. The entities for which the list is empty will be filtered out.

Example

[q|Entity, Name|]
  & qjoin (\(e1, n1) (e2, n2) -> n1 == n2 && e1 /= e2) (,) [q|Entity, Name|]
  & qinfo (\((e1, name), (e2, _)) -> [i|#{e1} and #{e2} are both named #{name}|])
  & query_

qcross :: (MonadSystem w m) => (a -> b -> Bool) -> Query m b -> Query m a -> Join m a List (From b) qcross f b a = Join a ( _ a -> do y <- query (qentity b) let y' = filter ((_, b) -> f a b) y pure $ map (uncurry From) y' )

Same as qcross but with side effects in the function which matches the elements of the two queries. qcrossM :: (MonadSystem w m) => (Entity -> a -> Entity -> b -> m Bool) -> Query m b -> Query m a -> Join m a List (From b) qcrossM f b a = Join a ( e a -> do y <- query (qentity b) y' <- filterM (uncurry (f e a)) y pure $ map (uncurry From) y' )

Extends the query with new elements.

Example

[q|Name|]
  & qextend qd|Position|
  & query

qentity :: forall w (m :: Type -> Type) a. MonadSystem w m => Query m a -> Query m (Entity, a) Source #

Traversal

qget :: forall w (m :: Type -> Type) qd out. (MonadSystem w m, Queryable qd out) => Entity -> qd -> Query m out Source #

qgetAll :: forall w (m :: Type -> Type) qd out. (MonadSystem w m, Queryable qd out) => [Entity] -> qd -> Query m out Source #

qrelateOne :: (MonadSystem w m, Queryable qd out) => (Entity -> m (Maybe Entity)) -> qd -> (a -> From out -> c) -> Query m a -> Query m c Source #

qrelateMany :: (MonadSystem w m, Queryable (E, qd) (Entity, out)) => (Entity -> m [Entity]) -> qd -> (a -> [From out] -> c) -> Query m a -> Query m c Source #

Joins

qjoin :: forall w (m :: Type -> Type) a b c. MonadSystem w m => (a -> Query m b) -> (a -> [From b] -> c) -> Query m a -> Query m c Source #

qrefocus :: forall (m :: Type -> Type) a. Entity -> Query m a -> Query m a Source #

qres :: forall {k} c (m :: Type -> Type) (a :: k) w. (MonadSystem w m, Component c) => Query m (Res c) Source #

Maps a resource into the query.

Example

[q|Name|]
  & qres @SomeResource (,)
  & query

qres :: forall r m a w. (MonadSystem w m, Component r) => Query m a -> Join m a Maybe (Res r) qres = qextend (mkQuery (Res @r))

qpure :: forall w (m :: Type -> Type). MonadSystem w m => Entity -> Query m () Source #

Logging

qinfo :: forall w (m :: Type -> Type) a. (HasCallStack, MonadSystem w m) => (a -> Text) -> Query m a -> Query m a Source #

Logs an INFO message.

qwarn :: forall w (m :: Type -> Type) a. (HasCallStack, MonadSystem w m) => (a -> Text) -> Query m a -> Query m a Source #

Logs a WARNING message.

qerr :: forall w (m :: Type -> Type) a. (HasCallStack, MonadSystem w m) => (a -> Text) -> Query m a -> Query m a Source #

Logs an ERROR message.