Aller au contenu

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);
ECS_RELATION_DECLARE(GroupOf);
ECS_RELATION_DEFINE(GroupOf, {
.storage = EcsRelationByTarget,
.on_delete_target = EcsRemoveRelation,
});
ECS_RELATION_REGISTER(GroupOf);
ecs_relate(member, 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.

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.

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 */
}

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.

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) },
});

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.

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.

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();

Le résultat visible est la cible finale. Consultez Observateurs pour recevoir les événements de ces transitions.