SanderMertens / flecs

A fast entity component system (ECS) for C & C++
https://www.flecs.dev
Other
6.47k stars 454 forks source link

COLUMN_INDEX_OUT_OF_RANGE when using iter.field<T>() with .oper(flecs::Or) #1000

Closed MeTheFlea closed 1 year ago

MeTheFlea commented 1 year ago

Describe the bug When using a system query with an OR term, I seem to be unable to get the value of the field out using iter.field<T>().

fatal: iter.hpp: 89: assert: m_array != nullptr COLUMN_INDEX_OUT_OF_RANGE

To Reproduce

struct Position {
    float x, y, z;
};
struct Velocity {
    float x, y, z;
};
flecs::world ecs;
ecs.entity().set<Position>( { 0.0f, 0.0f, 0.0f } );
ecs.entity().set<Velocity>( { 0.0f, 0.0f, 0.0f } );

auto s = ecs.system<>()
    .term<Position>().oper( flecs::Or )
    .term<Velocity>()
    .each( []( flecs::iter &iter, size_t index ) {
        if( iter.world().id<Position>() == iter.id( 1 )) {
            iter.field<Position>( 1 )[index]; // COLUMN_INDEX_OUT_OF_RANGE
        }
    } );
s.run();

Expected behavior iter.is_set(1) also returns true, so I expected to be able to get the value of the Position component in this query.

Additional context I'm not sure if I'm misunderstanding the API, but looking at the example here lead me to believe that this would be possible.

SanderMertens commented 1 year ago

Yup that's expected behavior. Field types must be static during iteration, which is why OR chains with different types aren't available as fields to the iterator.

What should (now- I just checked in a fix for an issue) work is the following code:

    auto s = ecs.system()
        .with<Position>().or_()
        .with<Velocity>()
        .each( []( flecs::iter &iter, size_t index ) {
            if( iter.world().id<Position>() == iter.id( 1 )) {
                const Position *p = &iter.range().get<Position>()[index];
            }
        } );

Also, congrats on creating the 1000th issue 🎉

MeTheFlea commented 1 year ago

Thank you! This seems to work correctly for me.

Also, congrats on creating the 1000th issue

Haha! Thanks for being so responsive and for the great project, still a bit new to using it but I've been having a good time playing around with it so far!

pfeodrippe commented 1 year ago

@SanderMertens Is the Or operator C example at https://www.flecs.dev/flecs/md_docs_Queries.html#autotoc_md206 still valid? So using ecs_field is not the right way anymore for this case? I can open a new issue if it's an issue =D

SanderMertens commented 1 year ago

Fixed it!

pfeodrippe commented 1 year ago

Fixed it!

WOW, thank you, man!