NYXA/src/scheduler/storage.zig

230 lines
5.9 KiB
Zig
Raw Normal View History

2026-08-03 16:54:23 +01:00
//! ----------------------------------------------------
//! ----------------------------------------------------
2026-07-09 22:30:04 +01:00
const std = @import("std");
const App = @import("../app.zig");
2026-07-09 22:30:04 +01:00
const System = @import("system.zig");
const TypeID = @import("../template/type_id.zig").of;
const Self = @This();
//
// FIELDS
//
data: std.ArrayList(System),
alloc: std.mem.Allocator,
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn init(alloc: std.mem.Allocator) Self {
return .{
.data = .empty,
.alloc = alloc,
};
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn deinit(self: *Self) void {
self.data.deinit(self.alloc);
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn add(
2026-07-09 22:30:04 +01:00
self: *Self,
comptime T: type,
execute: *const fn (*App) anyerror!void,
2026-07-09 22:30:04 +01:00
) !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);
2026-07-09 22:30:04 +01:00
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn addMany(
2026-07-09 22:30:04 +01:00
self: *Self,
comptime T: type,
values: []const *const fn (*App) anyerror!void,
) !void {
for (values) |exe| {
try self.add(T, exe);
}
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn addBefore(
self: *Self,
comptime Stage: type,
comptime Before: type,
execute: *const fn (*App) anyerror!void,
2026-07-09 22:30:04 +01:00
) !void {
const stage_id = TypeID(Stage);
const insert_idx = self.firstStageIndex(TypeID(Before));
2026-07-09 22:30:04 +01:00
try self.data.insert(self.alloc, insert_idx, .{
2026-07-09 22:30:04 +01:00
.stage_id = stage_id,
.execute = execute,
});
errdefer _ = self.data.swapRemove(insert_idx);
}
2026-07-09 22:30:04 +01:00
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn addManyBefore(
self: *Self,
comptime Stage: type,
comptime Before: type,
values: []const *const fn (*App) anyerror!void,
) !void {
const stage_id = TypeID(Stage);
var insert_idx = self.firstStageIndex(TypeID(Before));
for (values) |exe| {
try self.data.insert(self.alloc, insert_idx, .{
.stage_id = stage_id,
.execute = exe,
});
insert_idx += 1;
}
2026-07-09 22:30:04 +01:00
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn addAfter(
2026-07-09 22:30:04 +01:00
self: *Self,
comptime Stage: type,
comptime After: type,
execute: *const fn (*App) anyerror!void,
) !void {
const stage_id = TypeID(Stage);
const insert_idx = self.lastStageIndex(TypeID(After));
try self.data.insert(self.alloc, insert_idx, .{
.stage_id = stage_id,
.execute = execute,
});
errdefer _ = self.data.swapRemove(insert_idx);
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn addManyAfter(
self: *Self,
comptime Stage: type,
comptime After: type,
values: []const *const fn (*App) anyerror!void,
2026-07-09 22:30:04 +01:00
) !void {
const stage_id = TypeID(Stage);
var insert_idx = self.lastStageIndex(TypeID(After));
2026-07-09 22:30:04 +01:00
for (values) |exe| {
try self.data.insert(self.alloc, insert_idx, .{
.stage_id = stage_id,
.execute = exe,
});
insert_idx += 1;
}
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn runAll(
self: *Self,
app: *App,
) !void {
for (self.data.items) |sys| {
try sys.execute(app);
2026-07-09 22:30:04 +01:00
}
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn run(
self: *Self,
comptime T: type,
app: *App,
2026-07-09 22:30:04 +01:00
) !void {
// --- GET ID ---
const stage_id = TypeID(T);
// --- RUN ---
for (self.data.items) |sys| {
if (sys.stage_id != stage_id) continue;
try sys.execute(app);
2026-07-09 22:30:04 +01:00
}
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn runMany(
self: *Self,
comptime Ts: []const type,
app: *App,
2026-07-09 22:30:04 +01:00
) !void {
inline for (Ts) |T| {
try self.run(T, app);
}
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn runReversed(
self: *Self,
comptime T: type,
app: *App,
) !void {
// --- GET ID ---
const stage_id = TypeID(T);
// --- RUN ---
var i: usize = self.data.items.len;
while (i > 0) {
i -= 1;
const sys = self.data.items[i];
if (sys.stage_id != stage_id) continue;
try sys.execute(app);
}
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn runManyReversed(
self: *Self,
comptime Ts: []const type,
app: *App,
) !void {
inline for (Ts) |T| {
try self.runReversed(T, app);
2026-07-09 22:30:04 +01:00
}
}
/// ----------------------------------------------------
/// ----------------------------------------------------
fn firstStageIndex(self: *Self, stage_id: u64) usize {
for (self.data.items, 0..) |sys, i| {
if (sys.stage_id == stage_id) return i;
}
return self.data.items.len;
}
/// ----------------------------------------------------
/// ----------------------------------------------------
fn lastStageIndex(self: *Self, stage_id: u64) usize {
var last: usize = self.data.items.len;
for (self.data.items, 0..) |sys, i| {
if (sys.stage_id == stage_id) last = i + 1;
}
return last;
}