{-# LANGUAGE AllowAmbiguousTypes #-}
module Mischief.ECS.World.Utils where
import Control.Concurrent.STM
import Control.Monad
import Control.Monad.IO.Class (MonadIO (liftIO))
import Control.Monad.Primitive (PrimMonad (..))
import Control.Monad.Reader.Class (MonadReader (..), asks)
import Control.Monad.Trans (MonadTrans (..))
import Control.Monad.Trans.Reader (ReaderT (runReaderT))
import Data.Bifunctor qualified
import Data.IORef
import Data.List
import Data.Map qualified as Map
import Data.Maybe (fromMaybe, isNothing)
import Data.Proxy
import Data.Set (Set)
import Data.Set qualified as Set
import Data.Text (Text)
import Data.Typeable
import GHC.Stack
import Mischief.ECS.Archetypes
import Mischief.ECS.Components
import Mischief.ECS.Components.Bundle
import Mischief.ECS.Components.Spawn
import Mischief.ECS.Entities
import Mischief.ECS.EntityDef
import Mischief.ECS.EventDef
import Mischief.ECS.Hidden
import Mischief.ECS.Log
import Mischief.ECS.Tables
import Mischief.ECS.Utils
import Mischief.ECS.World
import Mischief.ECS.World.Prefs
processBundleElement :: World -> ComponentTicks -> (BundleElement ErasedComponent) -> IO ProcessedBundleElement
processBundleElement :: World
-> ComponentTicks
-> BundleElement ErasedComponent
-> IO ProcessedBundleElement
processBundleElement World
world ComponentTicks
ticks BundleElement {rep :: forall e. BundleElement e -> ComponentRep
rep = (ComponentRep ComponentType
r), ErasedComponent
component :: ErasedComponent
component :: forall e. BundleElement e -> e
component} =
do
id <- System ComponentId -> World -> IO ComponentId
forall a. System a -> World -> IO a
runSystem (ComponentType -> System ComponentId
getOrAddComponentId ComponentType
r) World
world
return
ProcessedBundleElement
{ id,
component =
ComponentData
{ value = component,
ticks
}
}
processBundleElement World
world ComponentTicks
ticks BundleElement {rep :: forall e. BundleElement e -> ComponentRep
rep = (PairRep (ComponentType
r, Entity
entity)), ErasedComponent
component :: forall e. BundleElement e -> e
component :: ErasedComponent
component} =
do
id <- System ComponentId -> World -> IO ComponentId
forall a. System a -> World -> IO a
runSystem (Pair -> System ComponentId
getOrAddPairId ((ComponentType, Entity) -> Pair
Pair (ComponentType
r, Entity
entity))) World
world
return
ProcessedBundleElement
{ id,
component =
ComponentData
{ value = component,
ticks
}
}
processBundleElements :: World -> ComponentTicks -> Set (BundleElement ErasedComponent) -> IO ProcessedBundleData
processBundleElements :: World
-> ComponentTicks
-> Set (BundleElement ErasedComponent)
-> IO ProcessedBundleData
processBundleElements World
world ComponentTicks
ticks Set (BundleElement ErasedComponent)
elements =
do
elements <- (BundleElement ErasedComponent -> IO ProcessedBundleElement)
-> [BundleElement ErasedComponent] -> IO [ProcessedBundleElement]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (World
-> ComponentTicks
-> BundleElement ErasedComponent
-> IO ProcessedBundleElement
processBundleElement World
world ComponentTicks
ticks) (Set (BundleElement ErasedComponent)
-> [BundleElement ErasedComponent]
forall a. Set a -> [a]
Set.toList Set (BundleElement ErasedComponent)
elements)
return
ProcessedBundleData {elements}
combineProcessedBundles :: ProcessedBundleData -> ProcessedBundleData -> ProcessedBundleData
combineProcessedBundles :: ProcessedBundleData -> ProcessedBundleData -> ProcessedBundleData
combineProcessedBundles ProcessedBundleData
bundle1 ProcessedBundleData
bundle2 =
let elements :: [ProcessedBundleElement]
elements = Set ProcessedBundleElement -> [ProcessedBundleElement]
forall a. Set a -> [a]
Set.toList (Set ProcessedBundleElement -> [ProcessedBundleElement])
-> Set ProcessedBundleElement -> [ProcessedBundleElement]
forall a b. (a -> b) -> a -> b
$ Set ProcessedBundleElement
-> Set ProcessedBundleElement -> Set ProcessedBundleElement
forall a. Ord a => Set a -> Set a -> Set a
Set.union ([ProcessedBundleElement] -> Set ProcessedBundleElement
forall a. Ord a => [a] -> Set a
Set.fromList ProcessedBundleData
bundle1.elements) ([ProcessedBundleElement] -> Set ProcessedBundleElement
forall a. Ord a => [a] -> Set a
Set.fromList ProcessedBundleData
bundle2.elements)
in ProcessedBundleData {[ProcessedBundleElement]
elements :: [ProcessedBundleElement]
elements :: [ProcessedBundleElement]
elements}
isInProcessedBundle :: ProcessedBundleData -> ComponentId -> Bool
isInProcessedBundle :: ProcessedBundleData -> ComponentId -> Bool
isInProcessedBundle ProcessedBundleData {[ProcessedBundleElement]
elements :: ProcessedBundleData -> [ProcessedBundleElement]
elements :: [ProcessedBundleElement]
elements} ComponentId
id = ComponentId
id ComponentId -> [ComponentId] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (ProcessedBundleElement -> ComponentId)
-> [ProcessedBundleElement] -> [ComponentId]
forall a b. (a -> b) -> [a] -> [b]
map (\ProcessedBundleElement
element -> ProcessedBundleElement
element.id) [ProcessedBundleElement]
elements
setChangedTickOfComponents :: ProcessedBundleData -> (ComponentId -> Bool) -> Tick -> ProcessedBundleData
setChangedTickOfComponents :: ProcessedBundleData
-> (ComponentId -> Bool) -> Tick -> ProcessedBundleData
setChangedTickOfComponents ProcessedBundleData {[ProcessedBundleElement]
elements :: ProcessedBundleData -> [ProcessedBundleElement]
elements :: [ProcessedBundleElement]
elements} ComponentId -> Bool
shouldChange Tick
tick =
ProcessedBundleData
{ elements :: [ProcessedBundleElement]
elements =
(ProcessedBundleElement -> ProcessedBundleElement)
-> [ProcessedBundleElement] -> [ProcessedBundleElement]
forall a b. (a -> b) -> [a] -> [b]
map
( \ProcessedBundleElement {ComponentId
id :: ProcessedBundleElement -> ComponentId
id :: ComponentId
id, component :: ProcessedBundleElement -> ComponentData
component = ComponentData {ErasedComponent
value :: ComponentData -> ErasedComponent
value :: ErasedComponent
value, ticks :: ComponentData -> ComponentTicks
ticks = ComponentTicks {Tick
added :: Tick
added :: ComponentTicks -> Tick
added, Tick
changed :: Tick
changed :: ComponentTicks -> Tick
changed}}} ->
if ComponentId -> Bool
shouldChange ComponentId
id
then ProcessedBundleElement {ComponentId
id :: ComponentId
id :: ComponentId
id, component :: ComponentData
component = ComponentData {ErasedComponent
value :: ErasedComponent
value :: ErasedComponent
value, ticks :: ComponentTicks
ticks = ComponentTicks {Tick
added :: Tick
added :: Tick
added, changed :: Tick
changed = Tick
tick}}}
else ProcessedBundleElement {ComponentId
id :: ComponentId
id :: ComponentId
id, component :: ComponentData
component = ComponentData {ErasedComponent
value :: ErasedComponent
value :: ErasedComponent
value, ticks :: ComponentTicks
ticks = ComponentTicks {Tick
added :: Tick
added :: Tick
added, Tick
changed :: Tick
changed :: Tick
changed}}}
)
[ProcessedBundleElement]
elements
}
setAddedTickOfComponents :: ProcessedBundleData -> (ComponentId -> Bool) -> Tick -> ProcessedBundleData
setAddedTickOfComponents :: ProcessedBundleData
-> (ComponentId -> Bool) -> Tick -> ProcessedBundleData
setAddedTickOfComponents ProcessedBundleData {[ProcessedBundleElement]
elements :: ProcessedBundleData -> [ProcessedBundleElement]
elements :: [ProcessedBundleElement]
elements} ComponentId -> Bool
shouldChange Tick
tick =
ProcessedBundleData
{ elements :: [ProcessedBundleElement]
elements =
(ProcessedBundleElement -> ProcessedBundleElement)
-> [ProcessedBundleElement] -> [ProcessedBundleElement]
forall a b. (a -> b) -> [a] -> [b]
map
( \ProcessedBundleElement {ComponentId
id :: ProcessedBundleElement -> ComponentId
id :: ComponentId
id, component :: ProcessedBundleElement -> ComponentData
component = ComponentData {ErasedComponent
value :: ComponentData -> ErasedComponent
value :: ErasedComponent
value, ticks :: ComponentData -> ComponentTicks
ticks = ComponentTicks {Tick
added :: ComponentTicks -> Tick
added :: Tick
added, Tick
changed :: ComponentTicks -> Tick
changed :: Tick
changed}}} ->
if ComponentId -> Bool
shouldChange ComponentId
id
then ProcessedBundleElement {ComponentId
id :: ComponentId
id :: ComponentId
id, component :: ComponentData
component = ComponentData {ErasedComponent
value :: ErasedComponent
value :: ErasedComponent
value, ticks :: ComponentTicks
ticks = ComponentTicks {added :: Tick
added = Tick
tick, Tick
changed :: Tick
changed :: Tick
changed}}}
else ProcessedBundleElement {ComponentId
id :: ComponentId
id :: ComponentId
id, component :: ComponentData
component = ComponentData {ErasedComponent
value :: ErasedComponent
value :: ErasedComponent
value, ticks :: ComponentTicks
ticks = ComponentTicks {Tick
added :: Tick
added :: Tick
added, Tick
changed :: Tick
changed :: Tick
changed}}}
)
[ProcessedBundleElement]
elements
}
removeComponentFromProcessedBundle :: ComponentId -> ProcessedBundleData -> ProcessedBundleData
removeComponentFromProcessedBundle :: ComponentId -> ProcessedBundleData -> ProcessedBundleData
removeComponentFromProcessedBundle ComponentId
componentId ProcessedBundleData
bundle =
do
let elements :: [ProcessedBundleElement]
elements = (ProcessedBundleElement -> Bool)
-> [ProcessedBundleElement] -> [ProcessedBundleElement]
forall a. (a -> Bool) -> [a] -> [a]
filter (\ProcessedBundleElement
x -> ProcessedBundleElement
x.id ComponentId -> ComponentId -> Bool
forall a. Eq a => a -> a -> Bool
/= ComponentId
componentId) ProcessedBundleData
bundle.elements
in ProcessedBundleData {[ProcessedBundleElement]
elements :: [ProcessedBundleElement]
elements :: [ProcessedBundleElement]
elements}
tryGetEntityRelCollection :: forall c. (Component c) => World -> Entity -> IO (Maybe (Maybe [Result (Rel c)]))
tryGetEntityRelCollection :: forall c.
Component c =>
World -> Entity -> IO (Maybe (Maybe [Result (Rel c)]))
tryGetEntityRelCollection World
world Entity
entity =
do
componentId <- TypeRep -> Components -> IO (Maybe ComponentId)
getComponentId (Proxy c -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (Proxy c -> TypeRep) -> Proxy c -> TypeRep
forall a b. (a -> b) -> a -> b
$ forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @c) World
world.components
case componentId of
Maybe ComponentId
Nothing -> Maybe (Maybe [Result (Rel c)])
-> IO (Maybe (Maybe [Result (Rel c)]))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Maybe [Result (Rel c)])
forall a. Maybe a
Nothing
Just ComponentId
componentId -> do
pointer <- Entity -> Entities -> IO (Maybe (IORef EntityPointer))
getPointer Entity
entity World
world.entities
case pointer of
Maybe (IORef EntityPointer)
Nothing -> do
Maybe (Maybe [Result (Rel c)])
-> IO (Maybe (Maybe [Result (Rel c)]))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Maybe [Result (Rel c)])
forall a. Maybe a
Nothing
Just IORef EntityPointer
pointer ->
do
pointer <- IORef EntityPointer -> IO EntityPointer
forall a. IORef a -> IO a
readIORef IORef EntityPointer
pointer
res <- tryGetRelCollectionFromTables world.tables entity pointer componentId
return $ Just res
tryGetEntityComponent :: forall c. (Component c) => World -> Entity -> IO (Maybe (Maybe c))
tryGetEntityComponent :: forall c. Component c => World -> Entity -> IO (Maybe (Maybe c))
tryGetEntityComponent World
world Entity
entity =
do
pointer <- Entity -> Entities -> IO (Maybe (IORef EntityPointer))
getPointer Entity
entity World
world.entities
case pointer of
Maybe (IORef EntityPointer)
Nothing -> Maybe (Maybe c) -> IO (Maybe (Maybe c))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Maybe c)
forall a. Maybe a
Nothing
Just IORef EntityPointer
pointer ->
do
componentId <- TypeRep -> Components -> IO (Maybe ComponentId)
getComponentId (Proxy c -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (Proxy c -> TypeRep) -> Proxy c -> TypeRep
forall a b. (a -> b) -> a -> b
$ forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @c) World
world.components
case componentId of
Maybe ComponentId
Nothing -> Maybe (Maybe c) -> IO (Maybe (Maybe c))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Maybe c) -> IO (Maybe (Maybe c)))
-> Maybe (Maybe c) -> IO (Maybe (Maybe c))
forall a b. (a -> b) -> a -> b
$ Maybe c -> Maybe (Maybe c)
forall a. a -> Maybe a
Just Maybe c
forall a. Maybe a
Nothing
Just ComponentId
componentId -> do
pointer <- IORef EntityPointer -> IO EntityPointer
forall a. IORef a -> IO a
readIORef IORef EntityPointer
pointer
res <- tryGetComponentFromTables world.tables pointer componentId
return $ Just res
tryGetEntityRel :: forall c. (Component c) => Entity -> World -> Entity -> IO (Maybe (Maybe c))
tryGetEntityRel :: forall c.
Component c =>
Entity -> World -> Entity -> IO (Maybe (Maybe c))
tryGetEntityRel Entity
target World
world Entity
entity =
do
pointer <- Entity -> Entities -> IO (Maybe (IORef EntityPointer))
getPointer Entity
entity World
world.entities
case pointer of
Maybe (IORef EntityPointer)
Nothing -> Maybe (Maybe c) -> IO (Maybe (Maybe c))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Maybe c)
forall a. Maybe a
Nothing
Just IORef EntityPointer
pointer ->
do
componentId <- TypeRep -> Components -> IO (Maybe ComponentId)
getComponentId (Proxy c -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (Proxy c -> TypeRep) -> Proxy c -> TypeRep
forall a b. (a -> b) -> a -> b
$ forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @c) World
world.components
case componentId of
Maybe ComponentId
Nothing -> Maybe (Maybe c) -> IO (Maybe (Maybe c))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Maybe c)
forall a. Maybe a
Nothing
Just (ComponentId (# Word#
id, Maybe Entity
_ #)) -> do
pointer <- IORef EntityPointer -> IO EntityPointer
forall a. IORef a -> IO a
readIORef IORef EntityPointer
pointer
res <- tryGetComponentFromTables world.tables pointer (ComponentId (# id, Just target #))
return $ Just res
tryGetRelCollections :: forall c. (Component c) => World -> [ArchetypeId] -> IO [(Entity, [Result (Rel c)])]
tryGetRelCollections :: forall c.
Component c =>
World -> [ArchetypeId] -> IO [(Entity, [Result (Rel c)])]
tryGetRelCollections World
world [ArchetypeId]
archetypes =
do
componentId <- TypeRep -> Components -> IO (Maybe ComponentId)
getComponentId (Proxy c -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (Proxy c -> TypeRep) -> Proxy c -> TypeRep
forall a b. (a -> b) -> a -> b
$ forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @c) World
world.components
case componentId of
Maybe ComponentId
Nothing -> [(Entity, [Result (Rel c)])] -> IO [(Entity, [Result (Rel c)])]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return []
Just ComponentId
componentId ->
Tables
-> [ArchetypeId] -> ComponentId -> IO [(Entity, [Result (Rel c)])]
forall c.
Component c =>
Tables
-> [ArchetypeId] -> ComponentId -> IO [(Entity, [Result (Rel c)])]
tryGetRelCollectionsFromTables World
world.tables [ArchetypeId]
archetypes ComponentId
componentId
tryGetComponents :: forall c. (Component c) => World -> [ArchetypeId] -> IO [(Entity, Result c)]
tryGetComponents :: forall c.
Component c =>
World -> [ArchetypeId] -> IO [(Entity, Result c)]
tryGetComponents World
world [ArchetypeId]
archetypes =
do
componentId <- TypeRep -> Components -> IO (Maybe ComponentId)
getComponentId (Proxy c -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (Proxy c -> TypeRep) -> Proxy c -> TypeRep
forall a b. (a -> b) -> a -> b
$ forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @c) World
world.components
case componentId of
Maybe ComponentId
Nothing -> [(Entity, Result c)] -> IO [(Entity, Result c)]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return []
Just ComponentId
componentId ->
Tables -> [ArchetypeId] -> ComponentId -> IO [(Entity, Result c)]
forall c.
Component c =>
Tables -> [ArchetypeId] -> ComponentId -> IO [(Entity, Result c)]
tryGetComponentsFromTables World
world.tables [ArchetypeId]
archetypes ComponentId
componentId
tryGetEntities :: World -> [ArchetypeId] -> IO [Entity]
tryGetEntities :: World -> [ArchetypeId] -> IO [Entity]
tryGetEntities World
world = Tables -> [ArchetypeId] -> IO [Entity]
tryGetEntitiesFromTables World
world.tables
tryGetRels :: forall c. (Component c) => Entity -> World -> [ArchetypeId] -> IO [(Entity, Result (Rel c))]
tryGetRels :: forall c.
Component c =>
Entity -> World -> [ArchetypeId] -> IO [(Entity, Result (Rel c))]
tryGetRels Entity
target World
world [ArchetypeId]
archetypes =
do
componentId <- TypeRep -> Components -> IO (Maybe ComponentId)
getComponentId (Proxy c -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (Proxy c -> TypeRep) -> Proxy c -> TypeRep
forall a b. (a -> b) -> a -> b
$ forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @c) World
world.components
case componentId of
Maybe ComponentId
Nothing -> [(Entity, Result (Rel c))] -> IO [(Entity, Result (Rel c))]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return []
Just ComponentId
componentId -> do
res <- Tables -> [ArchetypeId] -> ComponentId -> IO [(Entity, Result c)]
forall c.
Component c =>
Tables -> [ArchetypeId] -> ComponentId -> IO [(Entity, Result c)]
tryGetComponentsFromTables World
world.tables [ArchetypeId]
archetypes (Maybe Entity -> ComponentId -> ComponentId
setCompIdTarget (Entity -> Maybe Entity
forall a. a -> Maybe a
Just Entity
target) ComponentId
componentId)
return $ map (\(Entity
e, Result c
res) -> (Entity
e, (Rel c, Entity) -> Result (Rel c)
forall c. (c, Entity) -> Result c
Result (c -> Entity -> Rel c
forall c. c -> Entity -> Rel c
Rel (Result c -> c
forall c. Result c -> c
value Result c
res) Entity
target, Result c -> Entity
forall c. Result c -> Entity
entityOf Result c
res))) res
tryGetRelsMaybe :: forall c. (Component c) => Entity -> World -> [ArchetypeId] -> IO [(Entity, Maybe (Result (Rel c)))]
tryGetRelsMaybe :: forall c.
Component c =>
Entity
-> World -> [ArchetypeId] -> IO [(Entity, Maybe (Result (Rel c)))]
tryGetRelsMaybe Entity
target World
world [ArchetypeId]
archetypes =
do
componentId <- TypeRep -> Components -> IO (Maybe ComponentId)
getComponentId (Proxy c -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (Proxy c -> TypeRep) -> Proxy c -> TypeRep
forall a b. (a -> b) -> a -> b
$ forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @c) World
world.components
case componentId of
Maybe ComponentId
Nothing -> do
e <- World -> [ArchetypeId] -> IO [Entity]
tryGetEntities World
world [ArchetypeId]
archetypes
return $ map (,Nothing) e
Just ComponentId
componentId -> do
res <- Tables
-> [ArchetypeId] -> ComponentId -> IO [(Entity, Maybe (Result c))]
forall c.
Component c =>
Tables
-> [ArchetypeId] -> ComponentId -> IO [(Entity, Maybe (Result c))]
tryGetComponentsFromTablesMaybe World
world.tables [ArchetypeId]
archetypes (Maybe Entity -> ComponentId -> ComponentId
setCompIdTarget (Entity -> Maybe Entity
forall a. a -> Maybe a
Just Entity
target) ComponentId
componentId)
return $
map
( Data.Bifunctor.second
(fmap (\Result c
res -> (Rel c, Entity) -> Result (Rel c)
forall c. (c, Entity) -> Result c
Result (c -> Entity -> Rel c
forall c. c -> Entity -> Rel c
Rel (Result c -> c
forall c. Result c -> c
value Result c
res) Entity
target, Result c -> Entity
forall c. Result c -> Entity
entityOf Result c
res)))
)
res
tryGetComponentsMaybe :: forall c. (Component c) => World -> [ArchetypeId] -> IO [(Entity, Maybe (Result c))]
tryGetComponentsMaybe :: forall c.
Component c =>
World -> [ArchetypeId] -> IO [(Entity, Maybe (Result c))]
tryGetComponentsMaybe World
world [ArchetypeId]
archetypes =
do
componentId <- TypeRep -> Components -> IO (Maybe ComponentId)
getComponentId (Proxy c -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (Proxy c -> TypeRep) -> Proxy c -> TypeRep
forall a b. (a -> b) -> a -> b
$ forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @c) World
world.components
case componentId of
Maybe ComponentId
Nothing -> do
e <- World -> [ArchetypeId] -> IO [Entity]
tryGetEntities World
world [ArchetypeId]
archetypes
return $ map (,Nothing) e
Just ComponentId
componentId ->
Tables
-> [ArchetypeId] -> ComponentId -> IO [(Entity, Maybe (Result c))]
forall c.
Component c =>
Tables
-> [ArchetypeId] -> ComponentId -> IO [(Entity, Maybe (Result c))]
tryGetComponentsFromTablesMaybe World
world.tables [ArchetypeId]
archetypes ComponentId
componentId
tryGetTicks :: ComponentId -> World -> [ArchetypeId] -> IO [Maybe ComponentTicks]
tryGetTicks :: ComponentId -> World -> [ArchetypeId] -> IO [Maybe ComponentTicks]
tryGetTicks ComponentId
componentId World
world [ArchetypeId]
archetypes = Tables -> [ArchetypeId] -> ComponentId -> IO [Maybe ComponentTicks]
tryGetTicksFromTables World
world.tables [ArchetypeId]
archetypes ComponentId
componentId
tryGetEntityTicks :: Entity -> ComponentId -> World -> IO (Maybe ComponentTicks)
tryGetEntityTicks :: Entity -> ComponentId -> World -> IO (Maybe ComponentTicks)
tryGetEntityTicks Entity
entity ComponentId
componentId World
world = do
pointer <- Entity -> Entities -> IO (Maybe (IORef EntityPointer))
getPointer Entity
entity World
world.entities
case pointer of
Maybe (IORef EntityPointer)
Nothing -> Maybe ComponentTicks -> IO (Maybe ComponentTicks)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe ComponentTicks
forall a. Maybe a
Nothing
Just IORef EntityPointer
pointer -> do
pointer <- IORef EntityPointer -> IO EntityPointer
forall a. IORef a -> IO a
readIORef IORef EntityPointer
pointer
tryGetEntityTicksFromTables world.tables pointer componentId
isAlive :: forall m w. (MonadSystem w m) => Entity -> m Bool
isAlive :: forall (m :: * -> *) w. MonadSystem w m => Entity -> m Bool
isAlive Entity
entity = do
world <- m World
forall w (m :: * -> *). MonadSystem w m => m World
unsafeGetWorld
liftIO $ isAliveIO entity world.entities
expect :: (HasCallStack) => forall m w a. (MonadSystem w m) => Text -> Maybe a -> m a
expect :: forall (m :: * -> *) w a.
(HasCallStack, MonadSystem w m) =>
Text -> Maybe a -> m a
expect Text
t Maybe a
a = (HasCallStack => m a) -> m a
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => m a) -> m a) -> (HasCallStack => m a) -> m a
forall a b. (a -> b) -> a -> b
$ do
case Maybe a
a of
Maybe a
Nothing -> Text -> m ()
forall w (m :: * -> *).
(HasCallStack, MonadSystem w m) =>
Text -> m ()
panic Text
t m () -> (() -> m a) -> m a
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= m a -> () -> m a
forall a b. a -> b -> a
const m a
forall a. HasCallStack => a
undefined
Just a
x -> a -> m a
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
x
newtype GetSystem = GetSystem (forall c. (Component c) => Proxy c -> Entity -> System (Maybe c))