mischief-ecs-0.2.0.0: src/Mischief/ECS/Relationships/Order.hs
module Mischief.ECS.Relationships.Order where
import Data.Foldable
import Data.Maybe
import Data.Set (Set)
import Data.Set qualified as Set
import Mischief.ECS.Components
import Mischief.ECS.Entities
import Mischief.ECS.Utils
import Mischief.ECS.World
import Mischief.ECS.World.Insert
import Mischief.ECS.World.Query
import Mischief.ECS.World.Query.Markers
import Mischief.ECS.World.Query.QueryFilter
import Mischief.ECS.World.Remove
data Before = Before deriving (Component)
data Visited = Visited deriving (Component)
orderEntities :: [Entity] -> System [Entity]
orderEntities !entities = do
!res <- orderEntitiesStep (Set.fromList entities)
for_ entities $ remove (C @Visited)
-- err $ text res
pure res
orderEntitiesStep :: Set Entity -> System [Entity]
orderEntitiesStep !entities =
if null entities
then
return []
else do
!next <- expect "Attempted to Order Cyclic Graph!" <$> findM isAvailable entities
insert Visited next
(next :) <$> orderEntitiesStep (Set.delete next entities)
isAvailable :: Entity -> System Bool
isAvailable !entity = do
!before <- query $ mkQuery' E (With (R @Before entity))
isNothing <$> findM (\(!x) -> (not . unwrap <$>) $ single $ mkGet x (Has @Visited)) before