{-# LANGUAGE AllowAmbiguousTypes #-} {-# OPTIONS_GHC -Wno-redundant-constraints #-} module Mischief.ECS.Relationships.Graph where import Data.List import Mischief.ECS.Components import Mischief.ECS.Components.BundleTypes import Mischief.ECS.Entities import Mischief.ECS.World import Mischief.ECS.World.Query import Mischief.ECS.World.Query.Markers import Mischief.ECS.World.Query.QueryFilter (QueryFilter (With)) type family RelOutgoing b where RelOutgoing True = Maybe RelOutgoing False = List class ListToOutgoing b where listToOutgoing :: [Entity] -> b instance ListToOutgoing (Maybe Entity) where listToOutgoing :: [Entity] -> Maybe Entity listToOutgoing [Entity x] = Entity -> Maybe Entity forall a. a -> Maybe a Just Entity x listToOutgoing [Entity] _ = Maybe Entity forall a. Maybe a Nothing instance ListToOutgoing [Entity] where listToOutgoing :: [Entity] -> [Entity] listToOutgoing = [Entity] -> [Entity] forall a. a -> a id outgoing' :: forall c m w. (Component c, MonadSystem w m) => Entity -> m [Entity] outgoing' :: forall c (m :: * -> *) w. (Component c, MonadSystem w m) => Entity -> m [Entity] outgoing' Entity entity = do next <- Query m [Rel c] -> m (Maybe [Rel c]) forall w (m :: * -> *) out. MonadSystem w m => Query m out -> m (Maybe out) single (Query m [Rel c] -> m (Maybe [Rel c])) -> Query m [Rel c] -> m (Maybe [Rel c]) forall a b. (a -> b) -> a -> b $ Entity -> R' c Any -> Query m [Rel c] forall qd out (m :: * -> *). Queryable qd out => Entity -> qd -> Query m out mkGet Entity entity (forall {k} (a :: k) b. b -> R' a b forall a b. b -> R' a b R' @c Any Any) return $ case next of Maybe [Rel c] Nothing -> [] Just [Rel c] next -> (Rel c -> Entity) -> [Rel c] -> [Entity] forall a b. (a -> b) -> [a] -> [b] map (\Rel c x -> Rel c x.target) [Rel c] next outgoing :: forall c m w. (Component c, MonadSystem w m, ListToOutgoing (RelOutgoing (IsExclusiveRel c) Entity)) => Entity -> m (RelOutgoing (IsExclusiveRel c) Entity) outgoing :: forall c (m :: * -> *) w. (Component c, MonadSystem w m, ListToOutgoing (RelOutgoing (IsExclusiveRel c) Entity)) => Entity -> m (RelOutgoing (IsExclusiveRel c) Entity) outgoing Entity entity = [Entity] -> RelOutgoing (IsExclusiveRel c) Entity forall b. ListToOutgoing b => [Entity] -> b listToOutgoing ([Entity] -> RelOutgoing (IsExclusiveRel c) Entity) -> m [Entity] -> m (RelOutgoing (IsExclusiveRel c) Entity) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> forall c (m :: * -> *) w. (Component c, MonadSystem w m) => Entity -> m [Entity] outgoing' @c Entity entity incoming :: forall c m w. (Component c, BundleTypes c, MonadSystem w m) => Entity -> m [Entity] incoming :: forall c (m :: * -> *) w. (Component c, BundleTypes c, MonadSystem w m) => Entity -> m [Entity] incoming Entity entity = Query m Entity -> m [Entity] forall w (m :: * -> *) out. MonadSystem w m => Query m out -> m [out] query (Query m Entity -> m [Entity]) -> Query m Entity -> m [Entity] forall a b. (a -> b) -> a -> b $ E -> QueryFilter 'ArchetypeFilter -> Query m Entity forall qd out (m :: * -> *). Queryable qd out => qd -> QueryFilter 'ArchetypeFilter -> Query m out mkQuery' E E (R c Entity -> QueryFilter 'ArchetypeFilter forall a (f :: FilterType). ToFilterComponent a => a -> QueryFilter f With (forall {k} (a :: k) b. b -> R a b forall a b. b -> R a b R @c Entity entity))