{-# LANGUAGE AllowAmbiguousTypes #-}
{-# OPTIONS_GHC -Wno-redundant-constraints #-}
{-# OPTIONS_GHC -Wno-unused-foralls #-}

module Mischief.ECS.Components.Runnable where

import Data.Data
import Data.Kind
import Mischief.ECS.Components
import Mischief.ECS.Components.Bundle
import Mischief.ECS.World

class Runnable c where
  runFor' :: Proxy c -> (forall d. (Component d, Bundle d) => Proxy d -> System ()) -> System ()

instance {-# OVERLAPPABLE #-} (Component c, Bundle c) => Runnable c where
  runFor' :: Proxy c
-> (forall d. (Component d, Bundle d) => Proxy d -> System ())
-> System ()
runFor' Proxy c
c forall d. (Component d, Bundle d) => Proxy d -> System ()
s = Proxy c -> System ()
forall d. (Component d, Bundle d) => Proxy d -> System ()
s Proxy c
c

instance {-# OVERLAPPING #-} (Runnable r0, Runnable r1) => Runnable (r0, r1) where
  runFor' :: Proxy (r0, r1)
-> (forall d. (Component d, Bundle d) => Proxy d -> System ())
-> System ()
runFor' Proxy (r0, r1)
_ forall d. (Component d, Bundle d) => Proxy d -> System ()
s = do
    Proxy r0
-> (forall d. (Component d, Bundle d) => Proxy d -> System ())
-> System ()
forall {k} (c :: k).
Runnable c =>
Proxy c
-> (forall d. (Component d, Bundle d) => Proxy d -> System ())
-> System ()
runFor' (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @r0) Proxy d -> System ()
forall d. (Component d, Bundle d) => Proxy d -> System ()
s
    Proxy r1
-> (forall d. (Component d, Bundle d) => Proxy d -> System ())
-> System ()
forall {k} (c :: k).
Runnable c =>
Proxy c
-> (forall d. (Component d, Bundle d) => Proxy d -> System ())
-> System ()
runFor' (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @r1) Proxy d -> System ()
forall d. (Component d, Bundle d) => Proxy d -> System ()
s

runFor :: forall c. (Runnable c) => (forall (d :: Type). (Component d, Bundle d) => Proxy d -> System ()) -> System ()
runFor :: forall {k} (c :: k).
Runnable c =>
(forall d. (Component d, Bundle d) => Proxy d -> System ())
-> System ()
runFor = Proxy c
-> (forall d. (Component d, Bundle d) => Proxy d -> System ())
-> System ()
forall {k} (c :: k).
Runnable c =>
Proxy c
-> (forall d. (Component d, Bundle d) => Proxy d -> System ())
-> System ()
runFor' (forall (t :: k). Proxy t
forall {k} (t :: k). Proxy t
Proxy @c)