apecs-0.9.6: Fast Entity-Component-System library for game programming
Stabilityexperimental
Safe HaskellSafe-Inferred
LanguageHaskell2010

Apecs.Experimental.Children

Description

This module is experimental, and its API might change between point releases. Use at your own risk.

The default relation between an entity and a component value is one to zero or one. The entity may or may not have a value for the component, but if the component value exists, it belongs to an entity. This module enables setting multiple "child" component values rooted under the same "parent" entity, providing a one to many relation: the parent entity has zero or more child values of the component type. Concretely, these component values are of type Child c, belong to their own separate entities, and are explicitly linked to the parent entity.

Ad-hoc child relationships may be established without using this module by including a parent Entity in your component's type, but this is limiting in regards to traversing the relationship. Systems concerned with the relationship may only start from the child entities' component(s) and then fetch the parent entity's component(s). By expressing the relationship using this module, you get support for iteration over the parent-child relationship in whichever way is more convenient for your systems, i.e. you can map over child entities using the Child component then fetch the child entity's parent component(s) as needed, or you can map over the parent entities' ChildList component then fetch the child entities' component(s) as needed.

Some example use cases for this module:

  • Parent entity has a position defined in world space and child entities have data relative to the parent's position e.g. hitboxes, sprite animations, etc.
  • Parent entity is a leader and child entities are squad members e.g. a necromancer can summon skeletons

For an introduction to using this module, see the associated example.

Synopsis

Component

data Child c Source #

The Child component wraps the parent entity and the child entity's underlying component value.

If you want a Foo component in your game to be treated as a child component, specify the component type as Child Foo when declaring your world:

newtype Hitbox = Hitbox AABB deriving Show
instance Component Hitbox where type Storage Hitbox = Map Hitbox

-- A type alias solely for TH quoting's sake.
type ChildHitbox = Child Hitbox

makeWorld "World" [''ChildHitbox]

If your system is iterating over the Child component but does not need the parent entity, use the ChildValue pseudocomponent instead for better performance.

Note that if you delete a parent entity (i.e. destroy all of the parent entity's components), consider a destroy on the parent entity's children too. See ChildList for assistance on this. This is more from a memory management point of view than one of safety: nothing via standard usage of this library will break if a child "outlives" its parent. However, both trying to directly get some component value of a child's non-existent parent or trying to directly get a parent's non-existent ChildList will result in runtime errors. Raw use of get is inherently dangerous and its risk is not specific to the behavior provided by this module.

Constructors

Child !Entity !c 

Instances

Instances details
Component c => Component (Child c) Source # 
Instance details

Defined in Apecs.Experimental.Children

Associated Types

type Storage (Child c) Source #

Show c => Show (Child c) Source # 
Instance details

Defined in Apecs.Experimental.Children

Methods

showsPrec :: Int -> Child c -> ShowS #

show :: Child c -> String #

showList :: [Child c] -> ShowS #

Eq c => Eq (Child c) Source # 
Instance details

Defined in Apecs.Experimental.Children

Methods

(==) :: Child c -> Child c -> Bool #

(/=) :: Child c -> Child c -> Bool #

type Storage (Child c) Source # 
Instance details

Defined in Apecs.Experimental.Children

type Storage (Child c)

Pseudocomponents

newtype ChildValue c Source #

Accessor pseudocomponent that produces just the underlying component value as opposed to Child which also produces the parent entity.

For best performance, you should prefer ChildValue over Child if your system is iterating over children and does not need the parent entities.

Constructors

ChildValue c 

Instances

Instances details
(MonadIO m, Component c, Has w m (Child c)) => Has w m (ChildValue c) Source # 
Instance details

Defined in Apecs.Experimental.Children

Component c => Component (ChildValue c) Source # 
Instance details

Defined in Apecs.Experimental.Children

Associated Types

type Storage (ChildValue c) Source #

Show c => Show (ChildValue c) Source # 
Instance details

Defined in Apecs.Experimental.Children

Eq c => Eq (ChildValue c) Source # 
Instance details

Defined in Apecs.Experimental.Children

Methods

(==) :: ChildValue c -> ChildValue c -> Bool #

(/=) :: ChildValue c -> ChildValue c -> Bool #

type Storage (ChildValue c) Source # 
Instance details

Defined in Apecs.Experimental.Children

newtype ChildList c Source #

Pseudocomponent that produces all child entities for a parent.

A useful property of this pseudocomponent is that it may be destroyed, which does a cascading destroy on all of the parent's children:

-- Remove all of player 1 entity's hitboxes:
destroy player1 $ Proxy @(ChildList Hitbox)

The cascading destroy behavior is provided for convenience, but note that if you assigned additional components to the child entities, those components will not be destroyed. In this case, you should destroy all components on the children explicitly, e.g.:

ChildList children :: ChildList Hitbox <- get player1
for_ children $ \child -> do
  destroy child $ Proxy @ComponentsToDestroy

Constructors

ChildList (NonEmpty Entity) 

Instances

Instances details
(MonadIO m, Component c, Has w m (Child c)) => Has w m (ChildList c) Source # 
Instance details

Defined in Apecs.Experimental.Children

Component c => Component (ChildList c) Source # 
Instance details

Defined in Apecs.Experimental.Children

Associated Types

type Storage (ChildList c) Source #

Show (ChildList c) Source # 
Instance details

Defined in Apecs.Experimental.Children

Eq (ChildList c) Source # 
Instance details

Defined in Apecs.Experimental.Children

Methods

(==) :: ChildList c -> ChildList c -> Bool #

(/=) :: ChildList c -> ChildList c -> Bool #

type Storage (ChildList c) Source # 
Instance details

Defined in Apecs.Experimental.Children