1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
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, .{});
}
|