109 lines
3.3 KiB
Zig
109 lines
3.3 KiB
Zig
const std = @import("std");
|
|
const Allocator = std.mem.Allocator;
|
|
const components = @import("components.zig");
|
|
const sparse = @import("sparse.zig");
|
|
const Renderer = @import("renderer");
|
|
const Input = @import("sideros").Input;
|
|
const ecs = @import("ecs.zig");
|
|
|
|
pub const System = ecs.System;
|
|
pub const SystemGroup = []const System;
|
|
pub const SyncGroup = []const System;
|
|
|
|
pub const Resources = struct {
|
|
renderer: Renderer,
|
|
input: Input,
|
|
delta_time: f64 = 0.0,
|
|
};
|
|
|
|
pub const Human = struct {
|
|
position: components.Position,
|
|
speed: components.Speed,
|
|
};
|
|
|
|
// TODO(ernesto): Move pool to its own file
|
|
pub const Pool = struct {
|
|
humans: std.MultiArrayList(Human),
|
|
resources: Resources,
|
|
allocator: Allocator,
|
|
system_groups: std.ArrayList(SystemGroup),
|
|
sync_groups: std.ArrayList(SyncGroup),
|
|
thread_pool: *std.Thread.Pool,
|
|
wait_group: std.Thread.WaitGroup,
|
|
mutex: std.Thread.Mutex,
|
|
|
|
pub fn init(allocator: Allocator, resources: Resources) !@This() {
|
|
var pool = @This(){
|
|
.humans = .{},
|
|
.resources = resources,
|
|
.system_groups = std.ArrayList(SystemGroup).init(allocator),
|
|
.sync_groups = std.ArrayList(SystemGroup).init(allocator),
|
|
.thread_pool = try allocator.create(std.Thread.Pool),
|
|
.wait_group = .{},
|
|
.mutex = .{},
|
|
.allocator = allocator,
|
|
};
|
|
|
|
try pool.thread_pool.init(.{
|
|
.allocator = allocator,
|
|
.n_jobs = 4,
|
|
});
|
|
|
|
return pool;
|
|
}
|
|
|
|
pub fn addSystemGroup(self: *@This(), group: SystemGroup, sync: bool) !void {
|
|
if (sync) {
|
|
try self.sync_groups.append(group);
|
|
} else {
|
|
try self.system_groups.append(group);
|
|
}
|
|
}
|
|
|
|
pub fn deinit(self: *@This()) void {
|
|
self.humans.deinit(self.allocator);
|
|
|
|
self.system_groups.deinit();
|
|
self.sync_groups.deinit();
|
|
self.thread_pool.deinit();
|
|
self.allocator.destroy(self.thread_pool);
|
|
}
|
|
|
|
pub fn tick(self: *@This()) void {
|
|
for (0..self.system_groups.items.len) |i| {
|
|
self.thread_pool.spawnWg(&self.wait_group, struct {
|
|
fn run(pool: *Pool, index: usize) void {
|
|
const group = pool.system_groups.items[index];
|
|
for (group) |system| {
|
|
// TODO: system errors should be correctly handled
|
|
system(pool) catch unreachable;
|
|
}
|
|
}
|
|
}.run, .{ self, i });
|
|
}
|
|
for (0..self.sync_groups.items.len) |i| {
|
|
const group = self.sync_groups.items[i];
|
|
for (group) |system| {
|
|
system(self) catch unreachable;
|
|
}
|
|
}
|
|
}
|
|
|
|
fn getEntities(self: *@This(), T: type) *std.MultiArrayList(T) {
|
|
return switch (T) {
|
|
Human => &self.humans,
|
|
else => unreachable,
|
|
};
|
|
}
|
|
|
|
pub fn createEntity(self: *@This(), entity: anytype) !usize {
|
|
var list = self.getEntities(@TypeOf(entity));
|
|
const index = list.len;
|
|
try list.append(self.allocator, entity);
|
|
return index;
|
|
}
|
|
|
|
pub fn destroyEntity(self: *@This(), comptime T: type, entity: usize) void {
|
|
self.getEntities(T).swapRemove(entity);
|
|
}
|
|
};
|