diff --git a/src/editor/app.zig b/src/editor/app.zig index 1445c1d0..eff2201d 100755 --- a/src/editor/app.zig +++ b/src/editor/app.zig @@ -4,7 +4,8 @@ const core = mach.core; const gpu = mach.gpu; pub const name = .editor; -pub const App = mach.App(.{ mach.Module, @This() }); +pub const modules = .{ mach.Module, @This() }; +pub const App = mach.App; const UniformBufferObject = struct { resolution: @Vector(2, f32), @@ -24,8 +25,8 @@ fragment_shader_file: std.fs.File, fragment_shader_code: [:0]const u8, last_mtime: i128, -pub fn init(adapter: anytype) !void { - var editor = adapter.mod(.editor).state(); +pub fn init(eng: *mach.Engine) !void { + var editor = eng.mod(.editor).state(); core.setTitle("Mach editor"); @@ -82,8 +83,8 @@ pub fn init(adapter: anytype) !void { bgl.release(); } -pub fn deinit(adapter: anytype) !void { - var editor = adapter.mod(.editor).state(); +pub fn deinit(eng: *mach.Engine) !void { + var editor = eng.mod(.editor).state(); defer _ = gpa.deinit(); editor.fragment_shader_file.close(); @@ -93,16 +94,16 @@ pub fn deinit(adapter: anytype) !void { editor.bind_group.release(); } -pub fn tick(adapter: anytype) !void { - var editor = adapter.mod(.editor).state(); +pub fn tick(eng: *mach.Engine) !void { + var editor = eng.mod(.editor).state(); var iter = core.pollEvents(); while (iter.next()) |event| { switch (event) { .key_press => |ev| { - if (ev.key == .space) return adapter.send(.machExit); + if (ev.key == .space) return eng.send(.machExit); }, - .close => return adapter.send(.machExit), + .close => return eng.send(.machExit), else => {}, } } @@ -114,7 +115,7 @@ pub fn tick(adapter: anytype) !void { editor.fragment_shader_file.seekTo(0) catch unreachable; editor.fragment_shader_code = editor.fragment_shader_file.readToEndAllocOptions(allocator, std.math.maxInt(u32), null, 1, 0) catch |err| { std.log.err("Err: {}", .{err}); - return adapter.send(.machExit); + return eng.send(.machExit); }; editor.pipeline = recreatePipeline(editor.fragment_shader_code, null); } diff --git a/src/editor/main.zig b/src/editor/main.zig index c5058d9d..a9b51fc8 100644 --- a/src/editor/main.zig +++ b/src/editor/main.zig @@ -8,6 +8,8 @@ comptime { const std = @import("std"); const builtin = @import("builtin"); +// Forward "app" declarations into our namespace, such that @import("root").foo works as expected. +pub usingnamespace @import("app"); const App = @import("app").App; const core = @import("core"); const gpu = core.gpu; diff --git a/src/engine.zig b/src/engine.zig index f7ed9974..0c24ee2b 100644 --- a/src/engine.zig +++ b/src/engine.zig @@ -13,47 +13,61 @@ pub const Module = struct { pub const name = .mach; - pub fn machInit(adapter: anytype) !void { - var mach = adapter.mod(.mach); + pub fn machInit(eng: *Engine) !void { + var mach = eng.mod(.mach); core.allocator = allocator; try core.init(.{}); mach.state().device = core.device; mach.state().exit = false; - try adapter.send(.init); + try eng.send(.init); } - pub fn machDeinit(adapter: anytype) !void { - try adapter.send(.deinit); + pub fn machDeinit(eng: *Engine) !void { + try eng.send(.deinit); core.deinit(); - adapter.deinit(); + eng.deinit(); _ = gpa.deinit(); } - pub fn machExit(adapter: anytype) !void { - try adapter.send(.exit); - var state = adapter.mod(.mach).state(); + pub fn machExit(eng: *Engine) !void { + try eng.send(.exit); + var state = eng.mod(.mach).state(); state.exit = true; } }; -pub fn App(comptime modules: anytype) type { - return struct { - engine: ecs.World(modules), +pub const App = struct { + engine: Engine, - pub fn init(app: *@This()) !void { - app.* = .{ .engine = try ecs.World(modules).init(allocator) }; - try app.engine.send(.machInit); - } + pub fn init(app: *@This()) !void { + app.* = .{ .engine = try Engine.init(allocator) }; + try app.engine.send(.machInit); + } - pub fn deinit(app: *@This()) void { - try app.engine.send(.machDeinit); - } + pub fn deinit(app: *@This()) void { + try app.engine.send(.machDeinit); + } - pub fn update(app: *@This()) !bool { - try app.engine.send(.tick); - return app.engine.mod(.mach).state().exit; - } - }; + pub fn update(app: *@This()) !bool { + try app.engine.send(.tick); + return app.engine.mod(.mach).state().exit; + } +}; + +pub const Engine = ecs.World(modules()); + +fn Modules() type { + if (!@hasDecl(@import("root"), "modules")) { + @compileError("expected `pub const modules = .{};` in root file"); + } + return @TypeOf(@import("root").modules); +} + +fn modules() Modules() { + if (!@hasDecl(@import("root"), "modules")) { + @compileError("expected `pub const modules = .{};` in root file"); + } + return @import("root").modules; } diff --git a/src/gfx2d/Sprite2D.zig b/src/gfx2d/Sprite2D.zig index e7f20b61..05099daf 100644 --- a/src/gfx2d/Sprite2D.zig +++ b/src/gfx2d/Sprite2D.zig @@ -2,6 +2,7 @@ const std = @import("std"); const core = @import("core"); const gpu = core.gpu; const ecs = @import("ecs"); +const Engine = @import("../engine.zig").Engine; const math = @import("../math.zig"); const mat = math.mat; @@ -52,9 +53,9 @@ const Uniforms = extern struct { texture_size: Vec2 align(16), }; -pub fn machSprite2DInit(adapter: anytype) !void { - var mach = adapter.mod(.mach); - var sprite2d = adapter.mod(.mach_sprite2d); +pub fn machSprite2DInit(eng: *Engine) !void { + var mach = eng.mod(.mach); + var sprite2d = eng.mod(.mach_sprite2d); const device = mach.state().device; const uniform_buffer = device.createBuffer(&.{ @@ -70,7 +71,7 @@ pub fn machSprite2DInit(adapter: anytype) !void { .min_filter = .nearest, }); - const sprite_buffer_cap = 1024 * 128; // TODO: allow user to specify preallocation + const sprite_buffer_cap = 1024 * 256; // TODO: allow user to specify preallocation const sprite_transforms = device.createBuffer(&.{ .usage = .{ .storage = true, .copy_dst = true }, .size = @sizeOf(Mat4x4) * sprite_buffer_cap, @@ -156,8 +157,8 @@ pub fn machSprite2DInit(adapter: anytype) !void { shader_module.release(); } -pub fn deinit(adapter: anytype) !void { - var sprite2d = adapter.mod(.mach_sprite2d); +pub fn deinit(eng: *Engine) !void { + var sprite2d = eng.mod(.mach_sprite2d); sprite2d.state().texture.release(); sprite2d.state().pipeline.release(); @@ -169,9 +170,9 @@ pub fn deinit(adapter: anytype) !void { sprite2d.state().sprite_sizes.release(); } -pub fn tick(adapter: anytype) !void { - var mach = adapter.mod(.mach); - var sprite2d = adapter.mod(.mach_sprite2d); +pub fn tick(eng: *Engine) !void { + var mach = eng.mod(.mach); + var sprite2d = eng.mod(.mach_sprite2d); const device = mach.state().device; // Begin our render pass @@ -204,7 +205,7 @@ pub fn tick(adapter: anytype) !void { encoder.writeBuffer(sprite2d.state().uniform_buffer, 0, &[_]Uniforms{uniforms}); // Synchronize entity data into our GPU sprite buffer - var archetypes_iter = adapter.entities.query(.{ .all = &.{ + var archetypes_iter = eng.entities.query(.{ .all = &.{ .{ .mach_sprite2d = &.{ .uv_transform, .transform, @@ -213,20 +214,20 @@ pub fn tick(adapter: anytype) !void { } }); // TODO: eliminate these - var sprite_transforms = try std.ArrayListUnmanaged(Mat4x4).initCapacity(adapter.allocator, 1000); - defer sprite_transforms.deinit(adapter.allocator); - var sprite_uv_transforms = try std.ArrayListUnmanaged(Mat3x3).initCapacity(adapter.allocator, 1000); - defer sprite_uv_transforms.deinit(adapter.allocator); - var sprite_sizes = try std.ArrayListUnmanaged(Vec2).initCapacity(adapter.allocator, 1000); - defer sprite_sizes.deinit(adapter.allocator); + var sprite_transforms = try std.ArrayListUnmanaged(Mat4x4).initCapacity(eng.allocator, 1000); + defer sprite_transforms.deinit(eng.allocator); + var sprite_uv_transforms = try std.ArrayListUnmanaged(Mat3x3).initCapacity(eng.allocator, 1000); + defer sprite_uv_transforms.deinit(eng.allocator); + var sprite_sizes = try std.ArrayListUnmanaged(Vec2).initCapacity(eng.allocator, 1000); + defer sprite_sizes.deinit(eng.allocator); while (archetypes_iter.next()) |archetype| { var transforms = archetype.slice(.mach_sprite2d, .transform); var uv_transforms = archetype.slice(.mach_sprite2d, .uv_transform); var sizes = archetype.slice(.mach_sprite2d, .size); for (transforms, uv_transforms, sizes) |transform, uv_transform, size| { - try sprite_transforms.append(adapter.allocator, transform); - try sprite_uv_transforms.append(adapter.allocator, uv_transform); - try sprite_sizes.append(adapter.allocator, size); + try sprite_transforms.append(eng.allocator, transform); + try sprite_uv_transforms.append(eng.allocator, uv_transform); + try sprite_sizes.append(eng.allocator, size); } } const total_vertices = @as(u32, @intCast(sprite_sizes.items.len * 6)); diff --git a/src/main.zig b/src/main.zig index 8ea6c688..10fd1ee3 100644 --- a/src/main.zig +++ b/src/main.zig @@ -20,6 +20,7 @@ pub const Atlas = @import("atlas/Atlas.zig"); // Engine exports pub const App = @import("engine.zig").App; pub const Module = @import("engine.zig").Module; +pub const Engine = @import("engine.zig").Engine; const std = @import("std");