const builtin = @import("builtin"); const heap = @import("./heap.zig"); const map = @import("./map.zig"); const resource = @import("./resource.zig"); const std = @import("std"); const stack = @import("./stack.zig"); const system = @import("./system.zig"); thread_pool: ?*std.Thread.Pool = null, thread_restricted_resources: [std.enums.values(ThreadRestriction).len]resource.Table, event_systems: stack.Sequential(system.Schedule), pub const Event = enum (usize) { _ }; const Self = @This(); pub const ThreadRestriction = enum { none, main, }; pub fn create_event(self: *Self, label: []const u8) std.mem.Allocator.Error!Event { var systems = try system.Schedule.init(label); errdefer systems.deinit(); const index = self.event_systems.len(); try self.event_systems.push_grow(systems); return @enumFromInt(index); } pub fn deinit(self: *Self) void { for (&self.thread_restricted_resources) |*resources| { resources.deinit(); } for (self.event_systems.values) |*schedule| { schedule.deinit(); } if (self.thread_pool) |thread_pool| { thread_pool.deinit(); heap.allocator.destroy(thread_pool); } self.event_systems.deinit(); self.* = undefined; } pub fn get_resource(self: Self, thread_restriction: ThreadRestriction, comptime Resource: type) ?*Resource { return @ptrCast(@alignCast(self.thread_restricted_resources[@intFromEnum(thread_restriction)].get(Resource))); } pub fn set_get_resource(self: *Self, thread_restriction: ThreadRestriction, value: anytype) std.mem.Allocator.Error!*@TypeOf(value) { return self.thread_restricted_resources[@intFromEnum(thread_restriction)].set_get(value); } pub fn init(thread_count: u32) std.Thread.SpawnError!Self { var world = Self{ .thread_restricted_resources = .{resource.Table.init(), resource.Table.init()}, .event_systems = .{.allocator = heap.allocator}, }; if (thread_count != 0 and !builtin.single_threaded) { const thread_pool = try heap.allocator.create(std.Thread.Pool); try thread_pool.init(.{ .allocator = heap.allocator, .n_jobs = thread_count, }); world.thread_pool = thread_pool; } return world; } pub fn on_event(self: *Self, event: Event, action: *const system.Info, order: system.Order) std.mem.Allocator.Error!void { try self.event_systems.values[@intFromEnum(event)].then(self, action, order); } pub fn run_event(self: *Self, event: Event) anyerror!void { try self.event_systems.values[@intFromEnum(event)].run(self); } pub fn set_resource(self: *Self, thread_restriction: ThreadRestriction, value: anytype) std.mem.Allocator.Error!void { try self.thread_restricted_resources[@intFromEnum(thread_restriction)].set(value); }