{-# LANGUAGE UndecidableInstances, AllowAmbiguousTypes #-}
module Godot.Internal.Dispatch where
import Data.Kind
import Data.Proxy
import Data.Text (Text)
import GHC.TypeLits as T
import Godot.Gdnative.Internal.Gdnative
class HasBaseClass child where
type BaseClass child
super :: child -> BaseClass child
class parent :< child where
safeCast :: child -> parent
instance {-# OVERLAPPING #-} refl :< refl where
safeCast = id
instance {-# OVERLAPPABLE #-} (HasBaseClass c, pp :< BaseClass c) => pp :< c where
safeCast = safeCast . super
class Method (name :: Symbol) cls sig | cls name -> sig where
runMethod :: cls -> sig
instance {-# OVERLAPPABLE #-} (Method name (BaseClass child) sig, HasBaseClass child)
=> Method name child sig where
runMethod = runMethod @name . super
instance {-# OVERLAPPABLE #-} ( TypeError (T.Text "Couldn't find method " :<>: ShowType name
:<>: T.Text " with signature `" :<>: ShowType sig
:<>: T.Text "'.")
, Method name GodotObject sig )
=> Method name GodotObject sig where
runMethod = error "unreachable"
newtype Signal a = Signal Text
deriving (Show, Eq)