@@ -60744,6 +60744,7 @@ typedef enum {
6074460744 EcsRuleSelfUpId, /* Self|up traversal for fixed id (like AndId) */
6074560745 EcsRuleWith, /* Match id against fixed or variable source */
6074660746 EcsRuleTrav, /* Support for transitive/reflexive queries */
60747+ EcsRuleIds, /* Test for existence of ids matching wildcard */
6074760748 EcsRuleIdsRight, /* Find ids in use that match (R, *) wildcard */
6074860749 EcsRuleIdsLeft, /* Find ids in use that match (*, T) wildcard */
6074960750 EcsRuleEach, /* Iterate entities in table, populate entity variable */
@@ -61157,6 +61158,7 @@ const char* flecs_rule_op_str(
6115761158 case EcsRuleSelfUpId: return "selfupid";
6115861159 case EcsRuleWith: return "with ";
6115961160 case EcsRuleTrav: return "trav ";
61161+ case EcsRuleIds: return "ids ";
6116061162 case EcsRuleIdsRight: return "idsr ";
6116161163 case EcsRuleIdsLeft: return "idsl ";
6116261164 case EcsRuleEach: return "each ";
@@ -63114,10 +63116,18 @@ int flecs_rule_compile_term(
6311463116 if (!first_written || !second_written) {
6311563117 if (!first_written) {
6311663118 /* If first is unknown, traverse left: <- (*, t) */
63117- op.kind = EcsRuleIdsLeft;
63119+ if (term->first.id == EcsAny) {
63120+ op.kind = EcsRuleIds;
63121+ } else {
63122+ op.kind = EcsRuleIdsLeft;
63123+ }
6311863124 } else {
6311963125 /* If second is wildcard, traverse right: (r, *) -> */
63120- op.kind = EcsRuleIdsRight;
63126+ if (term->second.id == EcsAny) {
63127+ op.kind = EcsRuleIds;
63128+ } else {
63129+ op.kind = EcsRuleIdsRight;
63130+ }
6312163131 }
6312263132 op.src.entity = 0;
6312363133 op.flags &= (ecs_flags8_t)~(EcsRuleIsVar << EcsRuleSrc); /* ids has no src */
@@ -65041,6 +65051,48 @@ bool flecs_rule_trav(
6504165051 }
6504265052}
6504365053
65054+ static
65055+ bool flecs_rule_ids(
65056+ const ecs_rule_op_t *op,
65057+ bool redo,
65058+ const ecs_rule_run_ctx_t *ctx)
65059+ {
65060+ if (redo) {
65061+ return false;
65062+ }
65063+
65064+ ecs_rule_ids_ctx_t *op_ctx = flecs_op_ctx(ctx, ids);
65065+ ecs_id_record_t *cur;
65066+
65067+ {
65068+ ecs_id_t id = flecs_rule_op_get_id(op, ctx);
65069+ if (!ecs_id_is_wildcard(id)) {
65070+ /* If id is not a wildcard, we can directly return it. This can
65071+ * happen if a variable was constrained by an iterator. */
65072+ op_ctx->cur = NULL;
65073+ flecs_rule_set_vars(op, id, ctx);
65074+ return true;
65075+ }
65076+
65077+ cur = flecs_id_record_get(ctx->world, id);
65078+ if (!cur) {
65079+ return false;
65080+ }
65081+ }
65082+
65083+ flecs_rule_set_vars(op, cur->id, ctx);
65084+
65085+ if (op->field_index != -1) {
65086+ ecs_iter_t *it = ctx->it;
65087+ ecs_id_t id = flecs_rule_op_get_id_w_written(op, op->written, ctx);
65088+ it->ids[op->field_index] = id;
65089+ it->sources[op->field_index] = EcsWildcard;
65090+ it->columns[op->field_index] = -1; /* Mark field as set */
65091+ }
65092+
65093+ return true;
65094+ }
65095+
6504465096static
6504565097bool flecs_rule_idsright(
6504665098 const ecs_rule_op_t *op,
@@ -65084,6 +65136,8 @@ bool flecs_rule_idsright(
6508465136 ecs_iter_t *it = ctx->it;
6508565137 ecs_id_t id = flecs_rule_op_get_id_w_written(op, op->written, ctx);
6508665138 it->ids[op->field_index] = id;
65139+ it->sources[op->field_index] = EcsWildcard;
65140+ it->columns[op->field_index] = -1; /* Mark field as set */
6508765141 }
6508865142
6508965143 return true;
@@ -65132,6 +65186,8 @@ bool flecs_rule_idsleft(
6513265186 ecs_iter_t *it = ctx->it;
6513365187 ecs_id_t id = flecs_rule_op_get_id_w_written(op, op->written, ctx);
6513465188 it->ids[op->field_index] = id;
65189+ it->sources[op->field_index] = EcsWildcard;
65190+ it->columns[op->field_index] = -1; /* Mark field as set */
6513565191 }
6513665192
6513765193 return true;
@@ -66111,6 +66167,7 @@ bool flecs_rule_dispatch(
6611166167 case EcsRuleSelfUpId: return flecs_rule_self_up_id(op, redo, ctx);
6611266168 case EcsRuleWith: return flecs_rule_with(op, redo, ctx);
6611366169 case EcsRuleTrav: return flecs_rule_trav(op, redo, ctx);
66170+ case EcsRuleIds: return flecs_rule_ids(op, redo, ctx);
6611466171 case EcsRuleIdsRight: return flecs_rule_idsright(op, redo, ctx);
6611566172 case EcsRuleIdsLeft: return flecs_rule_idsleft(op, redo, ctx);
6611666173 case EcsRuleEach: return flecs_rule_each(op, redo, ctx);
0 commit comments