Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
MeTheFlea opened this issue Jul 4, 2023 · 5 comments
Closed
Labels
bug Something isn't working

Comments

@MeTheFlea
Copy link

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.

@MeTheFlea MeTheFlea added the bug Something isn't working label Jul 4, 2023
@SanderMertens
Copy link
Owner

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
Copy link
Author

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
Copy link
Contributor

pfeodrippe commented Aug 22, 2023

@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
Copy link
Owner

Fixed it!

@pfeodrippe
Copy link
Contributor

Fixed it!

WOW, thank you, man!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants