{-# LANGUAGE AllowAmbiguousTypes #-}
{-# OPTIONS_GHC -Wno-redundant-constraints #-}
module Mischief.ECS.World.Insert where
import Control.Exception
import Control.Monad
import Control.Monad.IO.Class
import Data.Foldable (for_)
import Data.IORef
import Data.List hiding (insert)
import Data.Set qualified as Set
import Data.Text qualified as T
import GHC.Base (Int (..))
import GHC.Stack
import Mischief.ECS.Archetypes.Graph
( getArchetypeOnInsert,
)
import Mischief.ECS.Components
import Mischief.ECS.Components.Bundle
import Mischief.ECS.Components.HooksDef (HookContext (..), HookContextRel (..))
import Mischief.ECS.Components.Spawn (ComponentAddHooks (ComponentAddHooks), ComponentAddHooksRel (ComponentAddHooksRel), ComponentSetHooks (ComponentSetHooks), ComponentSetHooksRel (ComponentSetHooksRel), meta)
import Mischief.ECS.Entities
import Mischief.ECS.EventDef
import Mischief.ECS.Events
import Mischief.ECS.Log
import Mischief.ECS.Tables
import Mischief.ECS.Vec qualified as Vec
import Mischief.ECS.World
import Mischief.ECS.World.Change
import Mischief.ECS.World.Prefs
import Mischief.ECS.World.Query
import Mischief.ECS.World.Query.Markers
import Mischief.ECS.World.Utils
data Exception' = Exception' deriving (Int -> Exception' -> ShowS
[Exception'] -> ShowS
Exception' -> String
(Int -> Exception' -> ShowS)
-> (Exception' -> String)
-> ([Exception'] -> ShowS)
-> Show Exception'
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Exception' -> ShowS
showsPrec :: Int -> Exception' -> ShowS
$cshow :: Exception' -> String
show :: Exception' -> String
$cshowList :: [Exception'] -> ShowS
showList :: [Exception'] -> ShowS
Show)
instance Exception Exception'
insert :: (HasCallStack) => forall b. (Bundle b) => b -> Entity -> System ()
insert :: forall b. (HasCallStack, Bundle b) => b -> Entity -> System ()
insert b
bundle Entity
entity =
do
world <- System World
forall w (m :: * -> *). MonadSystem w m => m World
unsafeGetWorld
pointer <- liftIO $ getPointer entity world.entities
case pointer of
Maybe (IORef EntityPointer)
Nothing -> Text -> System ()
forall w (m :: * -> *).
(HasCallStack, MonadSystem w m) =>
Text -> m ()
warn (Text -> System ()) -> Text -> System ()
forall a b. (a -> b) -> a -> b
$ Text
"Insertion failed: Entity " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Entity -> Text
forall a. Show a => a -> Text
T.show Entity
entity Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" is not alive."
Just IORef EntityPointer
currentPointer -> do
let BundleData {Set (BundleElement ErasedComponent)
elements :: Set (BundleElement ErasedComponent)
elements :: forall e. BundleData e -> Set (BundleElement e)
elements, Set (BundleElement ErasedComponent)
resources :: Set (BundleElement ErasedComponent)
resources :: forall e. BundleData e -> Set (BundleElement e)
resources, Set (Entity, BundleData ErasedComponent)
external :: Set (Entity, BundleData ErasedComponent)
external :: forall e. BundleData e -> Set (Entity, BundleData e)
external} = b -> BundleData ErasedComponent
forall b. Bundle b => b -> BundleData ErasedComponent
bundleData b
bundle
Set (Entity, BundleData ErasedComponent)
-> ((Entity, BundleData ErasedComponent) -> System ()) -> System ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ Set (Entity, BundleData ErasedComponent)
external (((Entity, BundleData ErasedComponent) -> System ()) -> System ())
-> ((Entity, BundleData ErasedComponent) -> System ()) -> System ()
forall a b. (a -> b) -> a -> b
$ \(Entity
e, BundleData ErasedComponent
x) -> do
forall b. (HasCallStack, Bundle b) => b -> Entity -> System ()
BundleData ErasedComponent -> Entity -> System ()
forall b. Bundle b => b -> Entity -> System ()
insert BundleData ErasedComponent
x Entity
e
Set (BundleElement ErasedComponent)
-> (BundleElement ErasedComponent -> System ()) -> System ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ Set (BundleElement ErasedComponent)
resources ((BundleElement ErasedComponent -> System ()) -> System ())
-> (BundleElement ErasedComponent -> System ()) -> System ()
forall a b. (a -> b) -> a -> b
$ \BundleElement {component :: forall e. BundleElement e -> e
component = ErasedComponent (c
val :: c)} -> do
m <- forall c. Component c => System Entity
meta @c
insert val m
currentTick <- IO Tick -> System Tick
forall a. IO a -> System a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Tick -> System Tick) -> IO Tick -> System Tick
forall a b. (a -> b) -> a -> b
$ IORef Tick -> IO Tick
forall a. IORef a -> IO a
readIORef World
world.tick
bundleData <- liftIO $ processBundleElements world ComponentTicks {changed = currentTick, added = currentTick} elements
let newComponents = [ComponentId] -> [ComponentId]
forall a. Ord a => [a] -> [a]
sort ([ComponentId] -> [ComponentId]) -> [ComponentId] -> [ComponentId]
forall a b. (a -> b) -> a -> b
$ (ProcessedBundleElement -> ComponentId)
-> [ProcessedBundleElement] -> [ComponentId]
forall a b. (a -> b) -> [a] -> [b]
map (\ProcessedBundleElement
x -> ProcessedBundleElement
x.id) ProcessedBundleData
bundleData.elements
(EntityPointer (# archetypeId, rowIndex #)) <- liftIO $ readIORef currentPointer
currentTable <- Vec.read world.tables.inner (I# archetypeId)
ChangeResult {requiredComponentsAdded, newComponents} <-
if newComponents `isSubsequenceOf` currentTable.components
then do
liftIO $ replaceComponentsIntoTable bundleData (Just currentTick) (EntityPointer (# archetypeId, rowIndex #)) currentTable
pure $ ChangeResult [] []
else do
newArchetype <- getArchetypeOnInsert (ArchetypeId $ I# archetypeId) newComponents
changeArchetype entity newArchetype (Just bundleData)
unless world.prefs.supressEvents $ do
triggerAddEvent (ProcessedBundleData newComponents) entity
triggerAddEvent (ProcessedBundleData requiredComponentsAdded) entity
triggerSetEvent bundleData entity
triggerSetEvent (ProcessedBundleData requiredComponentsAdded) entity
insertNew :: forall b. (Bundle b) => b -> Entity -> System ()
insertNew :: forall b. Bundle b => b -> Entity -> System ()
insertNew b
bundle Entity
entity =
do
let BundleData {Set (BundleElement ErasedComponent)
elements :: forall e. BundleData e -> Set (BundleElement e)
elements :: Set (BundleElement ErasedComponent)
elements, Set (BundleElement ErasedComponent)
resources :: forall e. BundleData e -> Set (BundleElement e)
resources :: Set (BundleElement ErasedComponent)
resources, Set (Entity, BundleData ErasedComponent)
external :: forall e. BundleData e -> Set (Entity, BundleData e)
external :: Set (Entity, BundleData ErasedComponent)
external} = b -> BundleData ErasedComponent
forall b. Bundle b => b -> BundleData ErasedComponent
bundleData b
bundle
Set (Entity, BundleData ErasedComponent)
-> ((Entity, BundleData ErasedComponent) -> System ()) -> System ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ Set (Entity, BundleData ErasedComponent)
external (((Entity, BundleData ErasedComponent) -> System ()) -> System ())
-> ((Entity, BundleData ErasedComponent) -> System ()) -> System ()
forall a b. (a -> b) -> a -> b
$ \(Entity
e, BundleData ErasedComponent
s) -> do
BundleData ErasedComponent -> Entity -> System ()
forall b. Bundle b => b -> Entity -> System ()
insertNew BundleData ErasedComponent
s Entity
e
world <- System World
forall w (m :: * -> *). MonadSystem w m => m World
unsafeGetWorld
pointer <- liftIO $ getPointer entity world.entities
case pointer of
Maybe (IORef EntityPointer)
Nothing -> Text -> System ()
forall w (m :: * -> *).
(HasCallStack, MonadSystem w m) =>
Text -> m ()
warn (Text -> System ()) -> Text -> System ()
forall a b. (a -> b) -> a -> b
$ Text
"Insertion failed: Entity " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Entity -> Text
forall a. Show a => a -> Text
T.show Entity
entity Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" is not alive."
Just IORef EntityPointer
currentPointer -> do
Set (BundleElement ErasedComponent)
-> (BundleElement ErasedComponent -> System ()) -> System ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ Set (BundleElement ErasedComponent)
resources ((BundleElement ErasedComponent -> System ()) -> System ())
-> (BundleElement ErasedComponent -> System ()) -> System ()
forall a b. (a -> b) -> a -> b
$ \BundleElement {component :: forall e. BundleElement e -> e
component = ErasedComponent (c
val :: c)} -> do
m <- forall c. Component c => System Entity
meta @c
r <- single $ mkGet m (C @c)
case r of
Just c
_ -> () -> System ()
forall a. a -> System a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Maybe c
Nothing -> c -> Entity -> System ()
forall b. (HasCallStack, Bundle b) => b -> Entity -> System ()
forall b. Bundle b => b -> Entity -> System ()
insert c
val Entity
m
currentTick <- IO Tick -> System Tick
forall a. IO a -> System a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Tick -> System Tick) -> IO Tick -> System Tick
forall a b. (a -> b) -> a -> b
$ IORef Tick -> IO Tick
forall a. IORef a -> IO a
readIORef World
world.tick
bundleData <- liftIO $ processBundleElements world ComponentTicks {changed = currentTick, added = currentTick} elements
(EntityPointer (# archetypeId, _ #)) <- liftIO $ readIORef currentPointer
currentTable <- Vec.read world.tables.inner (I# archetypeId)
let newComponents = [ProcessedBundleElement] -> ProcessedBundleData
ProcessedBundleData ([ProcessedBundleElement] -> ProcessedBundleData)
-> [ProcessedBundleElement] -> ProcessedBundleData
forall a b. (a -> b) -> a -> b
$ (ProcessedBundleElement -> Bool)
-> [ProcessedBundleElement] -> [ProcessedBundleElement]
forall a. (a -> Bool) -> [a] -> [a]
filter (\ProcessedBundleElement
c -> ProcessedBundleElement
c.id ComponentId -> [ComponentId] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` Table
currentTable.components) ProcessedBundleData
bundleData.elements
unless (null newComponents.elements) $ do
newArchetype <- getArchetypeOnInsert (ArchetypeId $ I# archetypeId) $ map (\ProcessedBundleElement
x -> ProcessedBundleElement
x.id) newComponents.elements
ChangeResult {requiredComponentsAdded} <- changeArchetype entity newArchetype (Just bundleData)
unless world.prefs.supressEvents $ do
triggerAddEvent (ProcessedBundleData requiredComponentsAdded) entity
triggerAddEvent newComponents entity
triggerSetEvent (ProcessedBundleData requiredComponentsAdded) entity
triggerSetEvent newComponents entity
insertIfNeq :: forall b. (BundleEq b) => b -> Entity -> System ()
insertIfNeq :: forall b. BundleEq b => b -> Entity -> System ()
insertIfNeq b
b Entity
entity = do
let BundleData {Set (BundleElement ErasedComponentEq)
elements :: forall e. BundleData e -> Set (BundleElement e)
elements :: Set (BundleElement ErasedComponentEq)
elements, Set (BundleElement ErasedComponentEq)
resources :: forall e. BundleData e -> Set (BundleElement e)
resources :: Set (BundleElement ErasedComponentEq)
resources, Set (Entity, BundleData ErasedComponentEq)
external :: forall e. BundleData e -> Set (Entity, BundleData e)
external :: Set (Entity, BundleData ErasedComponentEq)
external} = b -> BundleData ErasedComponentEq
forall b. BundleEq b => b -> BundleData ErasedComponentEq
bundleDataEq b
b
comps <- ((BundleElement ErasedComponentEq -> System Bool)
-> [BundleElement ErasedComponentEq]
-> System [BundleElement ErasedComponentEq])
-> [BundleElement ErasedComponentEq]
-> (BundleElement ErasedComponentEq -> System Bool)
-> System [BundleElement ErasedComponentEq]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (BundleElement ErasedComponentEq -> System Bool)
-> [BundleElement ErasedComponentEq]
-> System [BundleElement ErasedComponentEq]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM (Set (BundleElement ErasedComponentEq)
-> [BundleElement ErasedComponentEq]
forall a. Set a -> [a]
Set.toList Set (BundleElement ErasedComponentEq)
elements) ((BundleElement ErasedComponentEq -> System Bool)
-> System [BundleElement ErasedComponentEq])
-> (BundleElement ErasedComponentEq -> System Bool)
-> System [BundleElement ErasedComponentEq]
forall a b. (a -> b) -> a -> b
$ \BundleElement {ComponentRep
rep :: ComponentRep
rep :: forall e. BundleElement e -> ComponentRep
rep, component :: forall e. BundleElement e -> e
component = ErasedComponentEq (c
val :: c)} -> do
val' <- case ComponentRep
rep of
PairRep (ComponentType
_, Entity
target) -> (Rel c -> c) -> Maybe (Rel c) -> Maybe c
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Rel c
x -> Rel c
x.comp) (Maybe (Rel c) -> Maybe c)
-> System (Maybe (Rel c)) -> System (Maybe c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Query System (Rel c) -> System (Maybe (Rel c))
forall w (m :: * -> *) out.
MonadSystem w m =>
Query m out -> m (Maybe out)
single (Entity -> R c Entity -> Query System (Rel c)
forall qd out (m :: * -> *).
Queryable qd out =>
Entity -> qd -> Query m out
mkGet Entity
entity (forall {k} (a :: k) b. b -> R a b
forall a b. b -> R a b
R @c Entity
target))
ComponentRep
_ -> Query System c -> System (Maybe c)
forall w (m :: * -> *) out.
MonadSystem w m =>
Query m out -> m (Maybe out)
single (Entity -> C c -> Query System c
forall qd out (m :: * -> *).
Queryable qd out =>
Entity -> qd -> Query m out
mkGet Entity
entity (forall a. C a
forall {k} (a :: k). C a
C @c))
case val' of
Maybe c
Nothing -> Bool -> System Bool
forall a. a -> System a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
Just c
val' -> Bool -> System Bool
forall a. a -> System a
forall (m :: * -> *) a. Monad m => a -> m a
return (c
val c -> c -> Bool
forall a. Eq a => a -> a -> Bool
/= c
val')
resources <- flip filterM (Set.toList resources) $ \BundleElement {ComponentRep
rep :: forall e. BundleElement e -> ComponentRep
rep :: ComponentRep
rep, component :: forall e. BundleElement e -> e
component = ErasedComponentEq (c
val :: c)} -> do
e <- forall c. Component c => System Entity
meta @c
val' <- case rep of
ComponentRep ComponentType
_ -> Query System c -> System (Maybe c)
forall w (m :: * -> *) out.
MonadSystem w m =>
Query m out -> m (Maybe out)
single (Query System c -> System (Maybe c))
-> Query System c -> System (Maybe c)
forall a b. (a -> b) -> a -> b
$ Entity -> C c -> Query System c
forall qd out (m :: * -> *).
Queryable qd out =>
Entity -> qd -> Query m out
mkGet Entity
e (forall a. C a
forall {k} (a :: k). C a
C @c)
ComponentRep
_ -> System (Maybe c)
forall a. HasCallStack => a
undefined
case val' of
Maybe c
Nothing -> Bool -> System Bool
forall a. a -> System a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
Just c
val' -> Bool -> System Bool
forall a. a -> System a
forall (m :: * -> *) a. Monad m => a -> m a
return (c
val c -> c -> Bool
forall a. Eq a => a -> a -> Bool
/= c
val')
for_ external $ \(Entity
e, BundleData ErasedComponentEq
external) -> do
BundleData ErasedComponentEq -> Entity -> System ()
forall b. BundleEq b => b -> Entity -> System ()
insertIfNeq BundleData ErasedComponentEq
external Entity
e
System (ZonkAny 0)
forall a. HasCallStack => a
undefined
insert (bundleEqToSimple $ BundleData (Set.fromList comps) (Set.fromList resources) Set.empty) entity
triggerAddEvent :: ProcessedBundleData -> Entity -> System ()
triggerAddEvent :: ProcessedBundleData -> Entity -> System ()
triggerAddEvent ProcessedBundleData
bundle Entity
entity =
[ProcessedBundleElement]
-> (ProcessedBundleElement -> System ()) -> System ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ ProcessedBundleData
bundle.elements ((ProcessedBundleElement -> System ()) -> System ())
-> (ProcessedBundleElement -> System ()) -> System ()
forall a b. (a -> b) -> a -> b
$ \ProcessedBundleElement
x -> do
let !(ComponentId (# Word#
_, Maybe Entity
target #)) = ProcessedBundleElement
x.id
case Maybe Entity
target of
Maybe Entity
Nothing ->
ErasedComponent -> Entity -> System ()
triggerAddEventC ProcessedBundleElement
x.component.value Entity
entity
Just Entity
target ->
ErasedComponent -> Entity -> Entity -> System ()
triggerAddEventR ProcessedBundleElement
x.component.value Entity
target Entity
entity
triggerAddEventC :: ErasedComponent -> Entity -> System ()
triggerAddEventC :: ErasedComponent -> Entity -> System ()
triggerAddEventC (ErasedComponent (c
_ :: c)) Entity
entity = do
let context :: HookContext
context = HookContext {Entity
entity :: Entity
entity :: Entity
entity}
m <- forall c. Component c => System Entity
meta @c
hooks <- single $ mkGet m (C @ComponentAddHooks)
for_ hooks $ \(ComponentAddHooks [HookContext -> System ()]
h) -> do
[HookContext -> System ()]
-> ((HookContext -> System ()) -> System ()) -> System ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [HookContext -> System ()]
h (((HookContext -> System ()) -> System ()) -> System ())
-> ((HookContext -> System ()) -> System ()) -> System ()
forall a b. (a -> b) -> a -> b
$ \HookContext -> System ()
h -> HookContext -> System ()
h HookContext
context
runEvent $ eraseEvent $ OnAdd @c entity
triggerAddEventR :: ErasedComponent -> Entity -> Entity -> System ()
triggerAddEventR :: ErasedComponent -> Entity -> Entity -> System ()
triggerAddEventR (ErasedComponent (c
_ :: c)) Entity
target Entity
entity = do
let context :: HookContextRel
context = HookContextRel {Entity
entity :: Entity
entity :: Entity
entity, Entity
target :: Entity
target :: Entity
target}
m <- forall c. Component c => System Entity
meta @c
Just hooks <- single $ mkGet m (M @ComponentAddHooksRel)
for_ hooks $ \(ComponentAddHooksRel [HookContextRel -> System ()]
h) -> do
[HookContextRel -> System ()]
-> ((HookContextRel -> System ()) -> System ()) -> System ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [HookContextRel -> System ()]
h (((HookContextRel -> System ()) -> System ()) -> System ())
-> ((HookContextRel -> System ()) -> System ()) -> System ()
forall a b. (a -> b) -> a -> b
$ \HookContextRel -> System ()
h -> HookContextRel -> System ()
h HookContextRel
context
runEvent $ eraseEvent $ OnAddRel @c entity target
triggerSetEvent :: ProcessedBundleData -> Entity -> System ()
triggerSetEvent :: ProcessedBundleData -> Entity -> System ()
triggerSetEvent ProcessedBundleData
bundle Entity
entity =
[ProcessedBundleElement]
-> (ProcessedBundleElement -> System ()) -> System ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ ProcessedBundleData
bundle.elements ((ProcessedBundleElement -> System ()) -> System ())
-> (ProcessedBundleElement -> System ()) -> System ()
forall a b. (a -> b) -> a -> b
$ \ProcessedBundleElement
x -> do
let !(ComponentId (# Word#
_, Maybe Entity
target #)) = ProcessedBundleElement
x.id
case Maybe Entity
target of
Maybe Entity
Nothing ->
ErasedComponent -> Entity -> System ()
triggerSetEventC ProcessedBundleElement
x.component.value Entity
entity
Just Entity
target ->
ErasedComponent -> Entity -> Entity -> System ()
triggerSetEventR ProcessedBundleElement
x.component.value Entity
target Entity
entity
triggerSetEventC :: ErasedComponent -> Entity -> System ()
triggerSetEventC :: ErasedComponent -> Entity -> System ()
triggerSetEventC (ErasedComponent (c
_ :: c)) Entity
entity = do
let context :: HookContext
context = HookContext {Entity
entity :: Entity
entity :: Entity
entity}
m <- forall c. Component c => System Entity
meta @c
Just hooks <- single $ mkGet m (M @ComponentSetHooks)
for_ hooks $ \(ComponentSetHooks [HookContext -> System ()]
h) -> do
[HookContext -> System ()]
-> ((HookContext -> System ()) -> System ()) -> System ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [HookContext -> System ()]
h (((HookContext -> System ()) -> System ()) -> System ())
-> ((HookContext -> System ()) -> System ()) -> System ()
forall a b. (a -> b) -> a -> b
$ \HookContext -> System ()
h -> HookContext -> System ()
h HookContext
context
runEvent $ eraseEvent $ OnSet @c entity
triggerSetEventR :: ErasedComponent -> Entity -> Entity -> System ()
triggerSetEventR :: ErasedComponent -> Entity -> Entity -> System ()
triggerSetEventR (ErasedComponent (c
_ :: c)) Entity
target Entity
entity = do
let context :: HookContextRel
context = HookContextRel {Entity
entity :: Entity
entity :: Entity
entity, Entity
target :: Entity
target :: Entity
target}
m <- forall c. Component c => System Entity
meta @c
Just hooks <- single $ mkGet m (M @ComponentSetHooksRel)
for_ hooks $ \(ComponentSetHooksRel [HookContextRel -> System ()]
h) -> do
[HookContextRel -> System ()]
-> ((HookContextRel -> System ()) -> System ()) -> System ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [HookContextRel -> System ()]
h (((HookContextRel -> System ()) -> System ()) -> System ())
-> ((HookContextRel -> System ()) -> System ()) -> System ()
forall a b. (a -> b) -> a -> b
$ \HookContextRel -> System ()
h -> HookContextRel -> System ()
h HookContextRel
context
runEvent $ eraseEvent $ OnSetRel @c entity target