const std = @import("std"); const Allocator = std.mem.Allocator; const c = @import("./c.zig"); pub fn Iter(comptime ctx: anytype) type { return struct { const Self = @This(); const Context = @import("./context.zig").Context(ctx); const World = Context.World; const Entity = Context.Entity; const Id = Context.Id; world: *World, raw: *c.ecs_iter_t, allocator: ?Allocator, pub fn fromRawPtr(world: *World, ptr: *c.ecs_iter_t) Self { return .{ .world = world, .raw = ptr, .allocator = null }; } pub fn fromRawValue(world: *World, value: c.ecs_iter_t, allocator: Allocator) !Self { const raw = try allocator.create(c.ecs_iter_t); raw.* = value; return .{ .world = world, .raw = raw, .allocator = allocator }; } pub fn deinit(self: Self) void { if (self.isValid()) c.ecs_iter_fini(self.raw); if (self.allocator) |alloc| alloc.destroy(self.raw); } pub fn isValid(self: Self) bool { return (self.raw.flags & c.EcsIterIsValid) != 0; } pub fn count(self: Self) usize { return @intCast(self.raw.count); } pub fn deltaTime(self: Self) f32 { return self.raw.delta_time; } pub fn field(self: Self, comptime T: type, index: usize) []T { const raw_ptr = c.ecs_field_w_size(self.raw, @sizeOf(T), @intCast(index)); var typed_ptr: [*]T = @alignCast(@ptrCast(raw_ptr)); const is_self = c.ecs_field_is_self(self.raw, @intCast(index)); const count_ = if (is_self) self.count() else 1; return typed_ptr[0..count_]; } pub fn fieldId(self: Self, index: usize) Id { const raw = c.ecs_field_id(self.raw, @intCast(index)); return Id.fromRaw(self.world, raw); } pub fn fieldSource(self: Self, index: usize) Entity { const raw = c.ecs_field_src(self.raw, @intCast(index)); return Entity.fromRaw(self.world, raw); } }; }