mischief-ecs-0.2.0.0: src/Mischief/ECS/Components/Required.hs
{-# LANGUAGE AllowAmbiguousTypes #-}
module Mischief.ECS.Components.Required (require, requireAll, toBundleElement) where
import Data.Data
import Data.Default
import Data.Set (Set)
import Data.Set qualified as Set
import Mischief.ECS.Components
class RequiredBundle b where
defaultBundleData :: Proxy b -> Set DefaultComponentType
instance RequiredBundle () where
defaultBundleData :: Proxy () -> Set DefaultComponentType
defaultBundleData _ = Set.empty
instance {-# OVERLAPPABLE #-} (Component c, Default c) => RequiredBundle c where
defaultBundleData :: Proxy c -> Set DefaultComponentType
defaultBundleData _ = Set.singleton $ DefaultComponentType $ Proxy @c
instance {-# OVERLAPPING #-} (RequiredBundle b0, RequiredBundle b1) => RequiredBundle (b0, b1) where
defaultBundleData _ = Set.unions [defaultBundleData $ Proxy @b0, defaultBundleData $ Proxy @b1]
instance {-# OVERLAPPING #-} (RequiredBundle b0, RequiredBundle b1, RequiredBundle b2) => RequiredBundle (b0, b1, b2) where
defaultBundleData _ = Set.unions [defaultBundleData $ Proxy @b0, defaultBundleData $ Proxy @b1, defaultBundleData $ Proxy @b2]
instance {-# OVERLAPPING #-} (RequiredBundle b0, RequiredBundle b1, RequiredBundle b2, RequiredBundle b3) => RequiredBundle (b0, b1, b2, b3) where
defaultBundleData _ = Set.unions [defaultBundleData $ Proxy @b0, defaultBundleData $ Proxy @b1, defaultBundleData $ Proxy @b2, defaultBundleData $ Proxy @b3]
instance {-# OVERLAPPING #-} (RequiredBundle b0, RequiredBundle b1, RequiredBundle b2, RequiredBundle b3, RequiredBundle b4) => RequiredBundle (b0, b1, b2, b3, b4) where
defaultBundleData _ = Set.unions [defaultBundleData $ Proxy @b0, defaultBundleData $ Proxy @b1, defaultBundleData $ Proxy @b2, defaultBundleData $ Proxy @b3, defaultBundleData $ Proxy @b4]
instance {-# OVERLAPPING #-} (RequiredBundle b0, RequiredBundle b1, RequiredBundle b2, RequiredBundle b3, RequiredBundle b4, RequiredBundle b5) => RequiredBundle (b0, b1, b2, b3, b4, b5) where
defaultBundleData _ = Set.unions [defaultBundleData $ Proxy @b0, defaultBundleData $ Proxy @b1, defaultBundleData $ Proxy @b2, defaultBundleData $ Proxy @b3, defaultBundleData $ Proxy @b4, defaultBundleData $ Proxy @b5]
instance {-# OVERLAPPING #-} (RequiredBundle b0, RequiredBundle b1, RequiredBundle b2, RequiredBundle b3, RequiredBundle b4, RequiredBundle b5, RequiredBundle b6) => RequiredBundle (b0, b1, b2, b3, b4, b5, b6) where
defaultBundleData _ = Set.unions [defaultBundleData $ Proxy @b0, defaultBundleData $ Proxy @b1, defaultBundleData $ Proxy @b2, defaultBundleData $ Proxy @b3, defaultBundleData $ Proxy @b4, defaultBundleData $ Proxy @b5, defaultBundleData $ Proxy @b6]
instance {-# OVERLAPPING #-} (RequiredBundle b0, RequiredBundle b1, RequiredBundle b2, RequiredBundle b3, RequiredBundle b4, RequiredBundle b5, RequiredBundle b6, RequiredBundle b7) => RequiredBundle (b0, b1, b2, b3, b4, b5, b6, b7) where
defaultBundleData _ = Set.unions [defaultBundleData $ Proxy @b0, defaultBundleData $ Proxy @b1, defaultBundleData $ Proxy @b2, defaultBundleData $ Proxy @b3, defaultBundleData $ Proxy @b4, defaultBundleData $ Proxy @b5, defaultBundleData $ Proxy @b6, defaultBundleData $ Proxy @b7]
instance {-# OVERLAPPING #-} (RequiredBundle b0, RequiredBundle b1, RequiredBundle b2, RequiredBundle b3, RequiredBundle b4, RequiredBundle b5, RequiredBundle b6, RequiredBundle b7, RequiredBundle b8) => RequiredBundle (b0, b1, b2, b3, b4, b5, b6, b7, b8) where
defaultBundleData _ = Set.unions [defaultBundleData $ Proxy @b0, defaultBundleData $ Proxy @b1, defaultBundleData $ Proxy @b2, defaultBundleData $ Proxy @b3, defaultBundleData $ Proxy @b4, defaultBundleData $ Proxy @b5, defaultBundleData $ Proxy @b6, defaultBundleData $ Proxy @b7, defaultBundleData $ Proxy @b8]
instance {-# OVERLAPPING #-} (RequiredBundle b0, RequiredBundle b1, RequiredBundle b2, RequiredBundle b3, RequiredBundle b4, RequiredBundle b5, RequiredBundle b6, RequiredBundle b7, RequiredBundle b8, RequiredBundle b9) => RequiredBundle (b0, b1, b2, b3, b4, b5, b6, b7, b8, b9) where
defaultBundleData _ = Set.unions [defaultBundleData $ Proxy @b0, defaultBundleData $ Proxy @b1, defaultBundleData $ Proxy @b2, defaultBundleData $ Proxy @b3, defaultBundleData $ Proxy @b4, defaultBundleData $ Proxy @b5, defaultBundleData $ Proxy @b6, defaultBundleData $ Proxy @b7, defaultBundleData $ Proxy @b8, defaultBundleData $ Proxy @b9]
instance {-# OVERLAPPING #-} (RequiredBundle b0, RequiredBundle b1, RequiredBundle b2, RequiredBundle b3, RequiredBundle b4, RequiredBundle b5, RequiredBundle b6, RequiredBundle b7, RequiredBundle b8, RequiredBundle b9, RequiredBundle b10) => RequiredBundle (b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10) where
defaultBundleData _ = Set.unions [defaultBundleData $ Proxy @b0, defaultBundleData $ Proxy @b1, defaultBundleData $ Proxy @b2, defaultBundleData $ Proxy @b3, defaultBundleData $ Proxy @b4, defaultBundleData $ Proxy @b5, defaultBundleData $ Proxy @b6, defaultBundleData $ Proxy @b7, defaultBundleData $ Proxy @b8, defaultBundleData $ Proxy @b9, defaultBundleData $ Proxy @b10]
instance {-# OVERLAPPING #-} (RequiredBundle b0, RequiredBundle b1, RequiredBundle b2, RequiredBundle b3, RequiredBundle b4, RequiredBundle b5, RequiredBundle b6, RequiredBundle b7, RequiredBundle b8, RequiredBundle b9, RequiredBundle b10, RequiredBundle b11) => RequiredBundle (b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11) where
defaultBundleData _ = Set.unions [defaultBundleData $ Proxy @b0, defaultBundleData $ Proxy @b1, defaultBundleData $ Proxy @b2, defaultBundleData $ Proxy @b3, defaultBundleData $ Proxy @b4, defaultBundleData $ Proxy @b5, defaultBundleData $ Proxy @b6, defaultBundleData $ Proxy @b7, defaultBundleData $ Proxy @b8, defaultBundleData $ Proxy @b9, defaultBundleData $ Proxy @b10, defaultBundleData $ Proxy @b11]
instance {-# OVERLAPPING #-} (RequiredBundle b0, RequiredBundle b1, RequiredBundle b2, RequiredBundle b3, RequiredBundle b4, RequiredBundle b5, RequiredBundle b6, RequiredBundle b7, RequiredBundle b8, RequiredBundle b9, RequiredBundle b10, RequiredBundle b11, RequiredBundle b12) => RequiredBundle (b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12) where
defaultBundleData _ = Set.unions [defaultBundleData $ Proxy @b0, defaultBundleData $ Proxy @b1, defaultBundleData $ Proxy @b2, defaultBundleData $ Proxy @b3, defaultBundleData $ Proxy @b4, defaultBundleData $ Proxy @b5, defaultBundleData $ Proxy @b6, defaultBundleData $ Proxy @b7, defaultBundleData $ Proxy @b8, defaultBundleData $ Proxy @b9, defaultBundleData $ Proxy @b10, defaultBundleData $ Proxy @b11, defaultBundleData $ Proxy @b12]
instance {-# OVERLAPPING #-} (RequiredBundle b0, RequiredBundle b1, RequiredBundle b2, RequiredBundle b3, RequiredBundle b4, RequiredBundle b5, RequiredBundle b6, RequiredBundle b7, RequiredBundle b8, RequiredBundle b9, RequiredBundle b10, RequiredBundle b11, RequiredBundle b12, RequiredBundle b13) => RequiredBundle (b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13) where
defaultBundleData _ = Set.unions [defaultBundleData $ Proxy @b0, defaultBundleData $ Proxy @b1, defaultBundleData $ Proxy @b2, defaultBundleData $ Proxy @b3, defaultBundleData $ Proxy @b4, defaultBundleData $ Proxy @b5, defaultBundleData $ Proxy @b6, defaultBundleData $ Proxy @b7, defaultBundleData $ Proxy @b8, defaultBundleData $ Proxy @b9, defaultBundleData $ Proxy @b10, defaultBundleData $ Proxy @b11, defaultBundleData $ Proxy @b12, defaultBundleData $ Proxy @b13]
instance {-# OVERLAPPING #-} (RequiredBundle b0, RequiredBundle b1, RequiredBundle b2, RequiredBundle b3, RequiredBundle b4, RequiredBundle b5, RequiredBundle b6, RequiredBundle b7, RequiredBundle b8, RequiredBundle b9, RequiredBundle b10, RequiredBundle b11, RequiredBundle b12, RequiredBundle b13, RequiredBundle b14) => RequiredBundle (b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14) where
defaultBundleData _ = Set.unions [defaultBundleData $ Proxy @b0, defaultBundleData $ Proxy @b1, defaultBundleData $ Proxy @b2, defaultBundleData $ Proxy @b3, defaultBundleData $ Proxy @b4, defaultBundleData $ Proxy @b5, defaultBundleData $ Proxy @b6, defaultBundleData $ Proxy @b7, defaultBundleData $ Proxy @b8, defaultBundleData $ Proxy @b9, defaultBundleData $ Proxy @b10, defaultBundleData $ Proxy @b11, defaultBundleData $ Proxy @b12, defaultBundleData $ Proxy @b13, defaultBundleData $ Proxy @b14]
require :: forall b. (RequiredBundle b) => Set DefaultComponentType
require = defaultBundleData (Proxy @b)
requireAll :: forall c. (Component c) => Set DefaultComponentType
requireAll = requireAll' $ required @c
requireAll' :: Set DefaultComponentType -> Set DefaultComponentType
requireAll' !set =
let !nextSet = expandAll set
in if null nextSet then set else requireAll' $ Set.union set nextSet
expandAll :: Set DefaultComponentType -> Set DefaultComponentType
expandAll !set =
let !newSet = Set.unions $ map expandOne (Set.toList set)
in Set.difference newSet set
expandOne :: DefaultComponentType -> Set DefaultComponentType
expandOne (DefaultComponentType (_ :: (Proxy c))) = required @c
toBundleElement :: DefaultComponentType -> BundleElement ErasedComponent
toBundleElement (DefaultComponentType (_ :: (Proxy c))) = BundleElement (ComponentRep $ ComponentType $ Proxy @c) $ ErasedComponent $ def @c