mach icon indicating copy to clipboard operation
mach copied to clipboard

ecs: add query any

Open Vulfox opened this issue 1 year ago • 3 comments

A basic change-up of the query all to be used for the any query. Added a test that seems to be on par with the all test as is. If a separate test should be created for any, let me know. Also if this is not the intended design of any with what y'all have in mind, I am also down to adhering to any feedback.

What I really wanted was a query that would allow me to query all entities given a namespace, but figured an any call with all provided component names will do for now and saw it was panic-ing due to no implementation.

  • [x] By selecting this checkbox, I agree to license my contributions to this project under the license(s) described in the LICENSE file, and I have the right to do so or have received permission to do so by an employer or client I am producing work for whom has this right.

Vulfox avatar Mar 30 '24 23:03 Vulfox

Thanks for sending this, I am reworking querying quite a bit as part of https://github.com/hexops/mach/pull/1182 so may not merge this as-is due to some conflicts.

What I am very keen to understand is your use-case more specifically, to make sure I cover it. Can you share more details around it? What do the entities look like, and what's the motivation for querying all of them?

emidoots avatar Apr 02 '24 17:04 emidoots

Sure. I am dabbling in making a GUI lib with the ECS system you have here mostly as a learning project for using ECS and what entails making GUIs from scratch. With that said, I am highly certain that whatever pattern I have going on now ain't exactly the most efficient at what I would need it to be. The first step is collecting user input which is just polling and emitting whichever ones I care about and creating an entity under an Input namespace corresponding to whatever input was given like so:

pub const components = struct {
    pub const key_press = core.KeyEvent;
    pub const key_repeat = core.KeyEvent;
    pub const key_release = core.KeyEvent;
    pub const char_input = std.meta.TagPayload(core.Event, .char_input);
    pub const mouse_motion = std.meta.TagPayload(core.Event, .mouse_motion);
    pub const mouse_press = core.MouseButtonEvent;
    pub const mouse_release = core.MouseButtonEvent;
    pub const mouse_scroll = std.meta.TagPayload(core.Event, .mouse_scroll);
    pub const focus_gained = void;
    pub const focus_lost = void;
    pub const close = void;
};

To ensure the user input stuff gets cleaned up each loop, I want all .input namespaced components gone. Currently it looks like this:

        var archetypes_iter = engine.entities.query(.{
            .any = &.{
                .{ .input = &.{ .mouse_press, .mouse_release, .mouse_scroll } },
            },
        });
        while (archetypes_iter.next()) |archetype| {
            const ids = archetype.slice(.entity, .id);

            for (ids) |id| {
                try engine.entities.remove(id);
            }
        }

What I thought would have worked for the query was this:

        var archetypes_iter = engine.entities.query(.{
            .all = &.{ .{ .input = &.{} } },
        });

Where I want to select all of the input namespace, this way I don't have to individually be looking for each type of component. However the above seems to select all entities regardless of the namespace. Maybe a bug, but I am assuming it is intended.

I am not a fan of polling and emitting user input as I have it, but I do like the idea of creating a custom way to create inputs be it for automation or to allow for other input sources that aren't default to mouse and keyboard to create entities that correspond to a given action. This is a naive attempt, and I am currently thinking of ways of how I can reduce the amount of archetype lookups needed to get my input queue cleaned up and that might just need me to reduce the components down to 1 or 2 things which might become a list of some sort.

*edit: converted permalinked code to text

Vulfox avatar Apr 02 '24 19:04 Vulfox

Okay, this makes a lot of sense and seems like a good use-case to support.

Let me get back to you once I wrap up my work on #1182 to see how we can support this more optimally

emidoots avatar Apr 03 '24 15:04 emidoots

Taking this into consideration in a new API design for mach.Core

emidoots avatar Aug 25 '24 06:08 emidoots