NYXA/src/app.zig

153 lines
3.2 KiB
Zig

//! ----------------------------------------------------
//! ----------------------------------------------------
//
// PRIVATE
//
const std = @import("std");
const template = @import("template/root.zig");
const Self = @This();
//
// PUBLIC
//
pub const event = @import("event/root.zig");
pub const plugin = @import("plugin/root.zig");
pub const resource = @import("resource/root.zig");
pub const scheduler = @import("scheduler/root.zig");
pub const Plugin = plugin.Plugin;
pub const AppExit = event.AppExit;
/// ----------------------------------------------------
/// Default app stages
/// ----------------------------------------------------
pub const stage = struct {
// --- LIFETIME ---
pub const init = struct {};
pub const deinit = struct {};
// --- FRAME ---
pub const begin_frame = struct {};
pub const end_frame = struct {};
// --- CORE ---
pub const inputs = struct {};
pub const fixed_update = struct {};
pub const update = struct {};
pub const draw = struct {};
};
//
// FIELDS
//
events: event.Storage,
plugins: plugin.Storage,
resources: resource.Storage,
schedules: scheduler.Storage,
alloc: std.mem.Allocator,
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn init(alloc: std.mem.Allocator) Self {
return .{
.events = .init(alloc),
.plugins = .init(alloc),
.resources = .init(alloc),
.schedules = .init(alloc),
.alloc = alloc,
};
}
/// ----------------------------------------------------
/// ----------------------------------------------------
pub fn deinit(self: *Self) void {
self.events.deinit();
self.plugins.deinit();
self.resources.deinit();
self.schedules.deinit();
}
//
// TESTS
//
const Window = struct { raw: u32 };
const Renderer = struct { raw: u32 };
const window_plugin: Plugin = .{
.name = "Window",
.description = "SDL3 Window",
.build = build,
};
fn ensureStuff(app: *Self) !void {
try app.resources.setMany(.{
Window{ .raw = 0 },
Renderer{ .raw = 0 },
});
if (app.resources.getPtr(Window)) |win| {
std.debug.print("[WINDOW] {}\n", .{win.raw});
}
const res = try app.resources.getMany(struct {
window: *Window,
renderer: ?*Renderer,
});
if (res.renderer) |ren| {
std.debug.print("[RENDERER] {}\n", .{ren.raw});
}
try app.events.send(
AppExit{
.reason = "Why Not?",
},
);
if (app.events.consume(AppExit)) |app_exit| {
std.debug.print("[APP_EXIT] {s}\n", .{app_exit.reason});
}
}
fn build(
self: *Plugin,
app: *Self,
) !void {
std.debug.print(
"[WINDOW_PLUGIN] {s} - {s}\n",
.{
self.name,
self.description,
},
);
try app.schedules.addMany(stage.init, &.{
ensureStuff,
});
}
test "main" {
// --- APP ---
var app: Self = .init(std.testing.allocator);
defer app.deinit();
// --- ADD PLUGINS ---
try app.plugins.addMany(&.{
window_plugin,
});
try app.plugins.build(&app);
// --- RUN SYSTEMS ---
try app.schedules.runMany(
&.{
stage.init,
stage.deinit,
},
&app,
);
}