//! ---------------------------------------------------- //! ---------------------------------------------------- // // 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.set(Window{ .raw = 0 }); try app.resources.set(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, ); }