const std = @import("std"); const component = @import("component.zig"); const ComponentList = struct { entities: std.AutoHashMap(usize, component.Component), }; pub const EntityComponentSystem = struct { entities: std.ArrayList(usize), components: std.AutoHashMap(usize, ComponentList), available_ids: std.ArrayList(usize), next_id: usize, pub fn init(allocator: std.mem.Allocator) !EntityComponentSystem { var ecs = EntityComponentSystem{ .entities = std.ArrayList(usize).init(allocator), .components = std.AutoHashMap(usize, ComponentList).init(allocator), .available_ids = std.ArrayList(usize).init(allocator), .next_id = 0, }; inline for (std.meta.fields(component.ComponentType)) |comp| { try ecs.components.put(comp.value, ComponentList{ .entities = std.AutoHashMap(usize, component.Component).init(allocator), }); } return ecs; } pub fn deinit(self: *EntityComponentSystem) void { self.entities.deinit(); self.available_ids.deinit(); var component_iterator = self.components.iterator(); while (component_iterator.next()) |component_entry| { var comp = component_entry.value_ptr; var entity_iterator = comp.entities.iterator(); while (entity_iterator.next()) |entity_entry| { var entity = entity_entry.value_ptr; entity.deinit(); } comp.entities.deinit(); } self.components.deinit(); } pub fn createEntity(self: *EntityComponentSystem) !usize { const reuse_id = self.available_ids.popOrNull(); if (reuse_id != null and reuse_id.? < self.entities.items.len) { self.entities.items[reuse_id.?] = reuse_id.?; return reuse_id.?; } const id = self.next_id; try self.entities.append(id); self.next_id += 1; return id; } pub fn componentAddEntity( self: *EntityComponentSystem, comp: component.ComponentType, entity: usize, args: anytype, ) !void { var comp_list = self.components.getPtr(@intFromEnum(comp)) orelse return; try comp_list.entities.put(entity, component.Component.init(comp, args)); } }; test "add entities to components" { var ecs = try EntityComponentSystem.init(std.testing.allocator); defer ecs.deinit(); const entity = try ecs.createEntity(); try std.testing.expectEqual(0, entity); try ecs.componentAddEntity(component.ComponentType.component_stub, entity, .{}); }