SanderMertens / flecs

A fast entity component system (ECS) for C & C++

Home Page:https://www.flecs.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support superset queries for multiple relationship instances.

BHolman-LBI opened this issue · comments

Describe the bug
When a filter/query is matching a term supplied by a superset, an entity with multiples of that relation will be yielded multiple times but only on one of the relations.

To Reproduce
The following prints

Alice has rel with Bar
Alice has rel with Bar
struct SomeData
{
    std::string Name;
};

struct Rel{};

int main()
{
    flecs::world ecs;
    ecs.component<Rel>().add(flecs::Acyclic);

    ecs.entity("Alice")
        .add<Rel>(ecs.entity().set<SomeData>({"Foo"}))
        .add<Rel>(ecs.entity().set<SomeData>({"Bar"}));

    ecs.filter_builder<SomeData>()
        .arg(1).set(flecs::SuperSet, ecs.component<Rel>())
        .build().each([](flecs::iter& it, size_t i, SomeData& def){
            printf("%s has rel with %s\n", it.entity(i).str().c_str(), def.Name.c_str());
        });
    
    return 0;
}

Expected behavior
for it to yield Alice, once with Foo and once with Bar.

Removing the bug label as this behavior is currently unsupported - this is the same scenario as inheriting from multiple prefabs with the same component. I agree with the proposed solution, looking into how hard it is to get it in.

Note that the suggested behavior doesn't say anything about what should happen if the next level in the relationship has multiple instances of the relationship:

A -> B -> C -> SomeData
       -> D -> SomeData

It would be challenging to adapt the search algorithm to take this into account as it would require storing state for each level of the iteration which would be significantly more complex (and slower) than the current implementation.

The suggested behavior would only work for multiple relationship instances on the entity being matched.

Fixed!