mischief-ecs-0.1.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.Log
import Mischief.ECS.Tables
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.Query.Queryable
import Mischief.ECS.World.Remove
import Mischief.ECS.World.Spawn
import Mischief.ECS.World.Utils
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
return 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' E (With (R @Before entity))
isNothing <$> findM ((not . unwrap <$>) . get (Has @Visited)) before