From ebc09ee55ed2e1ec5aa10113860844ae913c37fb Mon Sep 17 00:00:00 2001 From: dweiller <4678790+dweiller@users.noreplay.github.com> Date: Wed, 13 Jul 2022 18:45:23 +1000 Subject: [PATCH] ecs: generic iterator type This change makes the the Iterator generic over the components being queried. This restores the api to the previous style with components given to the query() function and next() having no parameters (other that the iterator itself). --- ecs/src/entities.zig | 66 +++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/ecs/src/entities.zig b/ecs/src/entities.zig index cda8627e..3bc73c24 100644 --- a/ecs/src/entities.zig +++ b/ecs/src/entities.zig @@ -401,39 +401,43 @@ pub fn Entities(all_components: anytype) type { return @tagName(q) ++ "." ++ @tagName(@field(q, @tagName(std.meta.activeTag(q)))); } - pub const Iterator = struct { - entities: *Self, - archetype_index: usize = 0, - row_index: u32 = 0, + pub fn Iter(comptime components: []const Query) type { + return struct { + entities: *Self, + archetype_index: usize = 0, + row_index: u32 = 0, - pub const Entry = struct { - entity: EntityID, + const Iterator = @This(); - pub fn unlock(e: Entry) void { - _ = e; + pub const Entry = struct { + entity: EntityID, + + pub fn unlock(e: Entry) void { + _ = e; + } + }; + + pub fn next(iter: *Iterator) ?Entry { + const entities = iter.entities; + + // If the archetype table we're looking at does not contain the components we're + // querying for, keep searching through tables until we find one that does. + var archetype = entities.archetypes.entries.get(iter.archetype_index).value; + while (!hasComponents(archetype, components) or iter.row_index >= archetype.len) { + iter.archetype_index += 1; + iter.row_index = 0; + if (iter.archetype_index >= entities.archetypes.count()) { + return null; + } + archetype = entities.archetypes.entries.get(iter.archetype_index).value; + } + + const row_entity_id = archetype.get(iter.entities.allocator, iter.row_index, "id", EntityID).?; + iter.row_index += 1; + return Entry{ .entity = row_entity_id }; } }; - - pub fn next(iter: *Iterator, comptime components: []const Query) ?Entry { - const entities = iter.entities; - - // If the archetype table we're looking at does not contain the components we're - // querying for, keep searching through tables until we find one that does. - var archetype = entities.archetypes.entries.get(iter.archetype_index).value; - while (!hasComponents(archetype, components) or iter.row_index >= archetype.len) { - iter.archetype_index += 1; - iter.row_index = 0; - if (iter.archetype_index >= entities.archetypes.count()) { - return null; - } - archetype = entities.archetypes.entries.get(iter.archetype_index).value; - } - - const row_entity_id = archetype.get(iter.entities.allocator, iter.row_index, "id", EntityID).?; - iter.row_index += 1; - return Entry{ .entity = row_entity_id }; - } - }; + } fn hasComponents(storage: ArchetypeStorage, comptime components: []const Query) bool { var archetype = storage; @@ -444,8 +448,8 @@ pub fn Entities(all_components: anytype) type { return true; } - pub fn query(entities: *Self) Iterator { - return Iterator{ + pub fn query(entities: *Self, comptime components: []const Query) Iter(components) { + return Iter(components){ .entities = entities, }; }