// --- LIBS --- const std = @import("std"); const System = @import("system.zig"); const Context = @import("context.zig"); const TypeID = @import("../template/type_id.zig").of; const Self = @This(); // // FIELDS // data: std.ArrayList(System), stages: std.AutoHashMap(u64, usize), alloc: std.mem.Allocator, /// ---------------------------------------------------- /// ---------------------------------------------------- pub fn init(alloc: std.mem.Allocator) Self { return .{ .data = .empty, .stages = .init(alloc), .alloc = alloc, }; } /// ---------------------------------------------------- /// ---------------------------------------------------- pub fn deinit(self: *Self) void { self.data.deinit(self.alloc); self.stages.deinit(); } /// ---------------------------------------------------- /// ---------------------------------------------------- pub fn addStage( self: *Self, comptime T: type, ) !void { // --- GET ID --- const stage_id = TypeID(T); // --- INSERT --- if (self.stages.contains(stage_id)) return; try self.stages.put(stage_id, 0); } /// ---------------------------------------------------- /// ---------------------------------------------------- pub fn add( self: *Self, comptime T: type, execute: *const fn (Context) anyerror!void, ) !void { // --- GET ID --- const stage_id = TypeID(T); // --- NEW SYSTEM --- try self.data.append(self.alloc, .{ .stage_id = stage_id, .execute = execute, }); errdefer _ = self.data.swapRemove(self.data.items.len - 1); // --- NEW STAGE --- try self.addStage(T); } /// ---------------------------------------------------- /// ---------------------------------------------------- pub fn addMany( self: *Self, comptime T: type, values: []const *const fn (Context) anyerror!void, ) !void { for (values) |exe| { try self.add(T, exe); } } /// ---------------------------------------------------- /// ---------------------------------------------------- pub fn run( self: *Self, comptime T: type, ctx: Context, ) !void { // --- GET ID --- const stage_id = TypeID(T); // --- RUN --- for (self.data.items) |sys| { if (sys.stage_id != stage_id) continue; try sys.execute(ctx); } } /// ---------------------------------------------------- /// ---------------------------------------------------- pub fn runMany( self: *Self, comptime Ts: []const type, ctx: Context, ) !void { inline for (Ts) |T| { try self.run(T, ctx); } }