import { ValidationError } from "../core/index.js";
import { Bitset } from "./Bitset.js";
import {} from "./Component.js";
import {} from "./ComponentRegistry.js";
import {} from "./ComponentStore.js";
import {} from "./Entity.js";
import {} from "./EntityManager.js";
export class Query {
    entities;
    store;
    includeMask;
    excludeMask;
    include;
    exclude;
    constructor(entities, store, registry, options) {
        this.entities = entities;
        this.store = store;
        this.include = options.include ?? [];
        this.exclude = options.exclude ?? [];
        this.includeMask = Bitset.from(this.include.map((ctor) => registry.require(ctor).id));
        this.excludeMask = Bitset.from(this.exclude.map((ctor) => registry.require(ctor).id));
    }
    matches(entity) {
        const signature = this.store.signature(entity);
        return signature.containsAll(this.includeMask) && !signature.intersects(this.excludeMask);
    }
    toArray() {
        if (this.include.length === 1 && this.exclude.length === 0) {
            return this.store.entitiesWith(this.include[0]);
        }
        return this.entities.entities().filter((entity) => this.matches(entity));
    }
    forEach(visitor) {
        for (const entity of this.toArray())
            visitor(entity);
    }
    first() {
        return this.toArray()[0];
    }
    single() {
        const result = this.toArray();
        if (result.length !== 1)
            throw new ValidationError("QUERY_SINGLE", `Expected exactly one entity, found ${result.length}.`);
        return result[0];
    }
}
//# sourceMappingURL=Query.js.map