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

Assert during world clean up from observers modifying entities

BHolman-LBI opened this issue · comments

Describe the bug
The following triggers ecs_assert(component != 0, ECS_INTERNAL_ERROR, NULL); from flecs_get_c_info

To Reproduce

flecs::world ecs;
struct Position{ float X; float Y;};
struct ContainedBy{};
ecs.component<ContainedBy>();

ecs.observer()
    .term<ContainedBy>(flecs::Wildcard)
    .term<Position>().owned()
    .event(flecs::OnAdd)
    .each([](flecs::iter& Iter, size_t i)
    {
        flecs::entity e = Iter.entity(i);
        printf("Added to %s. Removing position from %s\n",
            Iter.pair(1).object().str().c_str(),
            e.str().c_str());
        e.remove<Position>();
    });

ecs.observer()
    .term<ContainedBy>(flecs::Wildcard)
    .event(flecs::OnRemove)
    .each([](flecs::iter& Iter, size_t i)
    {
        auto ParentPosition = Iter.pair(1).object().get<Position>();
        if(ParentPosition)
        {
            printf("Removed from %s. Setting position of %s to (%f, %f)\n",
                Iter.pair(1).object().str().c_str(),
                Iter.entity(i).str().c_str(),
                ParentPosition->X,
                ParentPosition->Y);
            Iter.entity(i).set<Position>(*ParentPosition);
        }
            
    });

auto chest = ecs.entity("Chest").set<Position>({1, 2});
auto food = ecs.entity("Food").set<Position>({5, 6});

food.add<ContainedBy>(chest);

Expected behavior
No Assertion

Reduced reproducing example to

flecs::world ecs;

struct Position { float x; float y; };
struct Tag { };

ecs.observer()
    .term<Tag>()
    .event(flecs::OnRemove)
    .each([](flecs::entity e)
    {
        e.set<Position>({});
    });

ecs.entity().add<Tag>();

Fixed!