From 1c9c65d8d28501d22246c88a9158ab2f4b88c724 Mon Sep 17 00:00:00 2001 From: copygirl Date: Sun, 19 Nov 2023 19:02:47 +0100 Subject: [PATCH] Add world.term (temporary?) --- src/world.zig | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/world.zig b/src/world.zig index 8f55240..b431a50 100644 --- a/src/world.zig +++ b/src/world.zig @@ -209,6 +209,41 @@ pub fn World(comptime ctx: anytype) type { } }; + /// Creates a term iterator which allows querying for all entities + /// that have a specific `Id`. This function supports wildcards. + pub fn term(self: *Self, id: anytype) TermIterator { + const id_ = util.anyToId(ctx, id); + var term_ = std.mem.zeroInit(c.ecs_term_t, .{ .id = id_ }); + const iter = c.ecs_term_iter(self.raw, &term_); + return .{ .world = self, .iter = iter }; + } + + // TODO: Move this logic to `Iter`, add `TermIter` type? + // TODO: Rename `Iter` to `Iterator`? + pub const TermIterator = struct { + world: *World(ctx), + iter: c.ecs_iter_t, + index: i32 = 0, + + pub fn next(self: *TermIterator) ?Entity(ctx) { + if (self.index >= self.iter.count) + if (!c.ecs_term_next(&self.iter)) + return null; + + const result = self.iter.entities[@intCast(self.index)]; + self.index += 1; + return Entity(ctx).fromRaw(self.world, result); + } + + // TODO: Check where else in the codebase it would make sense to have `deinit` take a pointer? + pub fn deinit(self: *TermIterator) void { + // Finalize the iterator if it hasn't run to completion. + if ((self.iter.flags & c.EcsIterIsValid) != 0) + c.ecs_iter_fini(&self.iter); + self.* = undefined; + } + }; + /// Gets the current scope of this `World`. See also: `setScope()`. pub fn getScope(self: *Self) ?Entity(ctx) { const result = c.ecs_get_scope(self.raw);