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

Querying from Multiple Entities at once doesn't work correctly #11

Open
Oreboat opened this issue Jan 28, 2025 · 1 comment
Open

Querying from Multiple Entities at once doesn't work correctly #11

Oreboat opened this issue Jan 28, 2025 · 1 comment

Comments

@Oreboat
Copy link

Oreboat commented Jan 28, 2025

I'm trying to query from multiple entities at once, however when I attempt to run the system it does not run unless both components exist on a single entity, a minimum reproduceable example of this issue is this

const Foo = struct 
{
    test_val1: u8
};
const Bar = struct 
{
    test_val2: u8
};

pub fn main() void{


    const world = flecs.init();
    defer _ = flecs.fini(world);

    flecs.COMPONENT(world, Foo);
    flecs.COMPONENT(world, Bar);

    const baz = flecs.new_entity(world, "baz");
    _ = flecs.set(world, baz, Foo, .{.test_val1 = 0});

    const qux =  flecs.new_entity(world, "qux");
    _ = flecs.set(world, qux, Bar, .{.test_val2 = 0});

    _ = flecs.ADD_SYSTEM_WITH_FILTERS(world, "quux", flecs.OnUpdate, quux, &.{
        .{.id = flecs.id(Foo)},
        .{.id = flecs.id(Bar), .src = .{.id = qux}}
    });

    _ = flecs.progress(world, 0);

}

fn quux(foo: []Foo, bar: []Bar) void {
    std.debug.print("system is working as intented", .{});

    for(foo)|*f|{
        _ = f;
        for(bar) |*b|{
            _ = b;
        }
    }
}

in this case, the system "quux" should run when there is an entity that has the variable "Foo" and the Entity "qux" with the component "Bar" however what actually happens is that unless the code is restructured to have "Foo" on "qux", the C version of this code (uses different names) dpes in fact work as intended

typedef struct {
    int a;
} Mesh;

typedef struct {
    int a;
} Camera;

void sys(ecs_iter_t *it) {
  printf("system ran\n");
}

int main() {
  ecs_world_t *world = ecs_init();

  ECS_COMPONENT(world, Mesh);
  ECS_COMPONENT(world, Camera);

  ecs_entity_t camera_entity = ecs_new(world);
  ecs_set(world, camera_entity, Camera, {0});

  ecs_entity_t e = ecs_new(world);
  ecs_set(world, e, Mesh, {0});

  ecs_system(world, {
    .entity = ecs_entity(world, { .add = ecs_ids(ecs_pair(EcsDependsOn, EcsOnUpdate))}),
    .query.terms = {
      { ecs_id(Mesh) },
      { ecs_id(Camera), .src.id = camera_entity }
    },
    .callback = sys
  });

  ecs_progress(world, 0);

  ecs_fini(world);
}
@Srekel
Copy link
Member

Srekel commented Jan 30, 2025

Hi,

Can you try this with the less sugar-coated C-ish syntax? As a reference here is how we write our systems on Tides:

fn updateCameraMatrices(it: *ecs.iter_t) callconv(.C) void {
    const ctx: *SystemUpdateContext = @alignCast(@ptrCast(it.ctx.?));

    const transforms = ecs.field(it, fd.Transform, 0).?;
    const cameras = ecs.field(it, fd.Camera, 1).?;
    for (cameras, transforms) |*cam, transform| {

Would help understand if it's a problem with how the systems are registered or how the callback is set up. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants