ecs: add query any
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.
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?
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
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
Taking this into consideration in a new API design for mach.Core