{-# LANGUAGE AllowAmbiguousTypes #-}
module Mischief.ECS.HooksRel
( addOther,
removeOther,
addDespawnCleaner,
addRemoveCleaner,
addCleaner,
removeCleaner,
)
where
import Data.Kind
import Mischief.ECS.Components
import Mischief.ECS.Components.HooksDef
import Mischief.ECS.EntityDef
import Mischief.ECS.Hooks
import Mischief.ECS.World
import Mischief.ECS.World.Insert
import Mischief.ECS.World.Query
import Mischief.ECS.World.Query.Markers
import Mischief.ECS.World.Remove
import Mischief.ECS.World.Spawn
addOther :: forall (a :: Type) b. (Component a, Component b) => (a -> b) -> HookRel a
addOther :: forall a b. (Component a, Component b) => (a -> b) -> HookRel a
addOther a -> b
f = (HookContextRel -> System ()) -> HookRel a
forall {k} (a :: k). (HookContextRel -> System ()) -> HookRel a
hookRel ((HookContextRel -> System ()) -> HookRel a)
-> (HookContextRel -> System ()) -> HookRel a
forall a b. (a -> b) -> a -> b
$ (a -> b) -> HookContextRel -> System ()
forall a b.
(Component b, Component a) =>
(a -> b) -> HookContextRel -> System ()
insertComplementary a -> b
f
removeOther :: forall a b. (Component b) => HookRel a
removeOther :: forall {k} (a :: k) b. Component b => HookRel a
removeOther = (HookContextRel -> System ()) -> HookRel a
forall {k} (a :: k). (HookContextRel -> System ()) -> HookRel a
hookRel ((HookContextRel -> System ()) -> HookRel a)
-> (HookContextRel -> System ()) -> HookRel a
forall a b. (a -> b) -> a -> b
$ forall b. Component b => HookContextRel -> System ()
removeComplementary @b
insertComplementary :: forall (a :: Type) b. (Component b, Component a) => (a -> b) -> HookContextRel -> System ()
insertComplementary :: forall a b.
(Component b, Component a) =>
(a -> b) -> HookContextRel -> System ()
insertComplementary a -> b
f HookContextRel
event = do
Just val <- Query System (Rel a) -> System (Maybe (Rel a))
forall w (m :: * -> *) out.
MonadSystem w m =>
Query m out -> m (Maybe out)
single (Query System (Rel a) -> System (Maybe (Rel a)))
-> Query System (Rel a) -> System (Maybe (Rel a))
forall a b. (a -> b) -> a -> b
$ Entity -> R a Entity -> Query System (Rel a)
forall qd out (m :: * -> *).
Queryable qd out =>
Entity -> qd -> Query m out
mkGet HookContextRel
event.entity (forall {k} (a :: k) b. b -> R a b
forall a b. b -> R a b
R @a HookContextRel
event.target)
insert (Rel (f val.comp) event.entity) event.target
removeComplementary :: forall b. (Component b) => HookContextRel -> System ()
removeComplementary :: forall b. Component b => HookContextRel -> System ()
removeComplementary HookContextRel
event = R b Entity -> Entity -> System ()
forall c. Collectable c ToRemove => c -> Entity -> System ()
remove (forall {k} (a :: k) b. b -> R a b
forall a b. b -> R a b
R @b HookContextRel
event.entity) HookContextRel
event.target
addCleaner :: forall (a :: Type). (Component a) => (CleanupRequest -> System ()) -> HookRel a
addCleaner :: forall a. Component a => (CleanupRequest -> System ()) -> HookRel a
addCleaner CleanupRequest -> System ()
f = (HookContextRel -> System ()) -> HookRel a
forall {k} (a :: k). (HookContextRel -> System ()) -> HookRel a
hookRel ((HookContextRel -> System ()) -> HookRel a)
-> (HookContextRel -> System ()) -> HookRel a
forall a b. (a -> b) -> a -> b
$ forall c.
Component c =>
(CleanupRequest -> System ()) -> HookContextRel -> System ()
insertCleanupWatcher @a CleanupRequest -> System ()
f
addRemoveCleaner :: forall (a :: Type). (Component a) => HookRel a
addRemoveCleaner :: forall a. Component a => HookRel a
addRemoveCleaner = forall a. Component a => (CleanupRequest -> System ()) -> HookRel a
addCleaner @a (\CleanupRequest
r -> forall c. Component c => Entity -> Entity -> System ()
removeRel @a CleanupRequest
r.target CleanupRequest
r.entity)
addDespawnCleaner :: forall (a :: Type). (Component a) => HookRel a
addDespawnCleaner :: forall a. Component a => HookRel a
addDespawnCleaner = forall a. Component a => (CleanupRequest -> System ()) -> HookRel a
addCleaner @a (\CleanupRequest
r -> Entity -> System ()
despawn CleanupRequest
r.entity)
insertCleanupWatcher :: forall c. (Component c) => (CleanupRequest -> System ()) -> HookContextRel -> System ()
insertCleanupWatcher :: forall c.
Component c =>
(CleanupRequest -> System ()) -> HookContextRel -> System ()
insertCleanupWatcher CleanupRequest -> System ()
f HookContextRel
e = forall b. (HasCallStack, Bundle b) => b -> Entity -> System ()
Rel (CleanupWatcher c) -> Entity -> System ()
forall b. Bundle b => b -> Entity -> System ()
insert (CleanupWatcher c -> Entity -> Rel (CleanupWatcher c)
forall c. c -> Entity -> Rel c
Rel (forall c. (CleanupRequest -> System ()) -> CleanupWatcher c
forall {k} (c :: k).
(CleanupRequest -> System ()) -> CleanupWatcher c
CleanupWatcher @c CleanupRequest -> System ()
f) HookContextRel
e.entity) HookContextRel
e.target
removeCleaner :: forall (a :: Type). (Component a) => HookRel a
removeCleaner :: forall a. Component a => HookRel a
removeCleaner = (HookContextRel -> System ()) -> HookRel a
forall {k} (a :: k). (HookContextRel -> System ()) -> HookRel a
hookRel (forall b. Component b => HookContextRel -> System ()
removeCleanupWatcher @a)
removeCleanupWatcher :: forall c. (Component c) => HookContextRel -> System ()
removeCleanupWatcher :: forall b. Component b => HookContextRel -> System ()
removeCleanupWatcher HookContextRel
e = do
forall b. (HasCallStack, Bundle b) => b -> Entity -> System ()
Rel (CleanupWatcher c) -> Entity -> System ()
forall b. Bundle b => b -> Entity -> System ()
insert (CleanupWatcher c -> Entity -> Rel (CleanupWatcher c)
forall c. c -> Entity -> Rel c
Rel (forall c. (CleanupRequest -> System ()) -> CleanupWatcher c
forall {k} (c :: k).
(CleanupRequest -> System ()) -> CleanupWatcher c
CleanupWatcher @c (() -> System ()
forall a. a -> System a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (() -> System ())
-> (CleanupRequest -> ()) -> CleanupRequest -> System ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. () -> CleanupRequest -> ()
forall a. a -> CleanupRequest -> a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())) HookContextRel
e.entity) HookContextRel
e.target
forall c. Component c => Entity -> Entity -> System ()
removeRel @(CleanupWatcher c) HookContextRel
e.entity HookContextRel
e.target
newtype CleanupWatcher c = CleanupWatcher {forall {k} (c :: k).
CleanupWatcher c -> CleanupRequest -> System ()
function :: CleanupRequest -> System ()}
data CleanupRequest = CleanupRequest
{ CleanupRequest -> Entity
entity :: Entity,
CleanupRequest -> Entity
target :: Entity
}
instance (Component c) => Component (CleanupWatcher c) where
onRemoveRel :: [HookRel (CleanupWatcher c)]
onRemoveRel = [(HookContextRel -> System ()) -> HookRel (CleanupWatcher c)
forall {k} (a :: k). (HookContextRel -> System ()) -> HookRel a
hookRel (forall b. Component b => HookContextRel -> System ()
triggerCleanup @c)]
triggerCleanup :: forall c. (Component c) => HookContextRel -> System ()
triggerCleanup :: forall b. Component b => HookContextRel -> System ()
triggerCleanup HookContextRel
e = do
Just watcher <- Query System (Rel (CleanupWatcher c))
-> System (Maybe (Rel (CleanupWatcher c)))
forall w (m :: * -> *) out.
MonadSystem w m =>
Query m out -> m (Maybe out)
single (Query System (Rel (CleanupWatcher c))
-> System (Maybe (Rel (CleanupWatcher c))))
-> Query System (Rel (CleanupWatcher c))
-> System (Maybe (Rel (CleanupWatcher c)))
forall a b. (a -> b) -> a -> b
$ Entity
-> R (CleanupWatcher c) Entity
-> Query System (Rel (CleanupWatcher c))
forall qd out (m :: * -> *).
Queryable qd out =>
Entity -> qd -> Query m out
mkGet HookContextRel
e.entity (forall {k} (a :: k) b. b -> R a b
forall a b. b -> R a b
R @(CleanupWatcher c) HookContextRel
e.target)
watcher.comp.function CleanupRequest {entity = e.target, target = e.entity}