Relations entre entités
Une relation connecte une entité source à une entité cible. Elle possède son
propre espace d’identifiants et se modifie avec ecs_relate() et
ecs_unrelate(), pas avec ecs_set().
ChildOf est la relation intégrée des hiérarchies. Elle est acyclique et
supprime les sources lorsqu’un parent est supprimé.
ecs_relate(child, ChildOf, parent);ecs_entity_t current = ecs_target(child, ChildOf);ecs_unrelate(child, ChildOf);child.child_of(parent);auto current = child.target<ecs::ChildOf>();child.unrelate<ecs::ChildOf>();Déclarer une relation personnalisée
Section intitulée « Déclarer une relation personnalisée »ECS_RELATION_DECLARE(GroupOf);ECS_RELATION_DEFINE(GroupOf, { .storage = EcsRelationByTarget, .on_delete_target = EcsRemoveRelation,});
ECS_RELATION_REGISTER(GroupOf);ecs_relate(member, GroupOf, group);struct GroupOf {};
ecs::relation<GroupOf>({ .storage = EcsRelationByTarget, .on_delete_target = EcsRemoveRelation,});
auto member = ecs::entity::create().relate<GroupOf>(group);Une relation déclarée est enregistrée une fois par monde. Pour une relation
créée dynamiquement, utilisez ecs_relation_init() et un ecs_relation_desc_t.
Choisir un stockage
Section intitulée « Choisir un stockage »| Stockage | Cas d’usage | Requêtes associées |
|---|---|---|
EcsRelationDense |
Cible stockée par source | ecs_rel, ecs_targets() |
EcsRelationByDepth |
Hiérarchie acyclique | ecs_depth, ordre par profondeur |
EcsRelationByTarget |
Beaucoup de sources pour une cible | ecs_to, ordre par cible |
ByDepth exige .acyclic = true. ecs_to() exige ByTarget. Les fonctions
de profondeur exigent ByDepth. Le choix se fait selon la requête dominante,
pas selon la seule forme du graphe.
Inspecter une relation
Section intitulée « Inspecter une relation »if (ecs_has_relation(source, GroupOf)) { ecs_entity_t target = ecs_target(source, GroupOf);}
if (ecs_has_relation_to(source, GroupOf, group)) { /* source pointe exactement vers group */}if (source.has_relation<GroupOf>()) { auto target = source.target<GroupOf>();}
if (source.target<GroupOf>().id() == group.id()) { // source pointe exactement vers group}La cible est un handle complet avec génération. La remplacer par une autre cible réoriente la relation ; la réappliquer avec la même cible ne fait rien.
Interroger les relations
Section intitulée « Interroger les relations »Les relations filtrent les tables ; elles ne créent pas de champ composant.
ecs_query_id_t members = ecs_query({ .components = { ecs_in(Position) }, .relations = { ecs_to(GroupOf, group) },});auto members = ecs::query() .require<Position>() .to<GroupOf>(group) .build_handle();ecs_rel() exige une relation, ecs_rel_opt() la rend optionnelle,
ecs_not_rel() l’exclut, ecs_to() filtre une cible exacte et ecs_depth()
filtre une profondeur. ecs_targets() fournit des cibles contiguës pour
Dense et ByDepth, et ecs_target_shared() lit la cible partagée d’un batch
ByTarget.
Suppression de la cible
Section intitulée « Suppression de la cible »La politique on_delete_target définit le comportement lorsqu’une cible meurt :
| Politique | Effet |
|---|---|
EcsRemoveRelation |
Retire la relation ; les sources restent vivantes. |
EcsDeleteSources |
Supprime les sources qui pointent vers la cible. |
Ces transitions déclenchent les mêmes événements de relation que les opérations explicites.
Changements différés
Section intitulée « Changements différés »Pendant un système ou une portée différée, les transitions sont appliquées au flush :
ecs_defer_begin();ecs_relate(source, GroupOf, first_group);ecs_relate(source, GroupOf, final_group);ecs_defer_end();ecs_defer_begin(); source.relate<GroupOf>(first_group); source.relate<GroupOf>(final_group);ecs_defer_end();Le résultat visible est la cible finale. Consultez Observateurs pour recevoir les événements de ces transitions.