From 8082228186c637fbd16944c535d6f3cf5dd05eb7 Mon Sep 17 00:00:00 2001 From: Stephen Gutekanst Date: Tue, 17 Jan 2023 00:05:16 -0700 Subject: [PATCH] mach: eliminate heap allocation of Core Prior to this change `mach.Core.init` would heap allocate the structure, returning `*Core`: ```zig app.core = try mach.Core.init(allocator, .{}); ``` This was obviously not ideal, but wasn't possible to eliminate before due to how Core was entangled with the platform abstraction. Now that it has been removed, we can reduce Core initialization to take a `*Core` to initialize. In practice this means initialization looks something like this: ```zig try mach.Core.init(&app.core, alloctor, .{}); ``` Or more simply: ```zig try app.core.init(allocator, .{}); ``` And we eliminate the `*Core` allocation entirely in most cases. Signed-off-by: Stephen Gutekanst --- src/Core.zig | 8 +++----- src/engine.zig | 9 +++++---- src/platform/native/Core.zig | 18 ++++++------------ src/platform/wasm/Core.zig | 8 ++------ 4 files changed, 16 insertions(+), 27 deletions(-) diff --git a/src/Core.zig b/src/Core.zig index 008675a2..fa8719f0 100644 --- a/src/Core.zig +++ b/src/Core.zig @@ -5,7 +5,7 @@ const platform = @import("platform.zig"); pub const Core = @This(); -internal: *platform.Core, +internal: platform.Core, pub const Options = struct { is_app: bool = false, @@ -16,10 +16,8 @@ pub const Options = struct { required_limits: ?gpu.Limits = null, }; -pub fn init(allocator: std.mem.Allocator, options: Options) !Core { - return .{ - .internal = try platform.Core.init(allocator, options), - }; +pub fn init(core: *Core, allocator: std.mem.Allocator, options: Options) !void { + try platform.Core.init(&core.internal, allocator, options); } pub fn deinit(core: *Core) void { diff --git a/src/engine.zig b/src/engine.zig index 8f6bcf86..c47a6c83 100644 --- a/src/engine.zig +++ b/src/engine.zig @@ -25,15 +25,16 @@ pub fn App( return struct { engine: ecs.World(modules), + core: Core, pub fn init(app: *@This()) !void { + try app.core.init(allocator, .{}); app.* = .{ + .core = app.core, .engine = try ecs.World(modules).init(allocator), }; - var core = try allocator.create(Core); - core.* = try Core.init(allocator, .{}); - app.engine.set(.mach, .core, core); - app.engine.set(.mach, .device, core.device()); + app.engine.set(.mach, .core, &app.core); + app.engine.set(.mach, .device, app.core.device()); try app_init(&app.engine); } diff --git a/src/platform/native/Core.zig b/src/platform/native/Core.zig index 8f115c56..f27136c6 100644 --- a/src/platform/native/Core.zig +++ b/src/platform/native/Core.zig @@ -52,7 +52,7 @@ const UserPtr = struct { self: *Core, }; -pub fn init(allocator: std.mem.Allocator, options: Options) !*Core { +pub fn init(core: *Core, allocator: std.mem.Allocator, options: Options) !void { const backend_type = try util.detectBackendType(allocator); glfw.setErrorCallback(errorCallback); @@ -153,9 +153,7 @@ pub fn init(allocator: std.mem.Allocator, options: Options) !*Core { }; const swap_chain = gpu_device.createSwapChain(surface, &swap_chain_desc); - const self: *Core = try allocator.create(Core); - errdefer allocator.destroy(self); - self.* = .{ + core.* = .{ .allocator = allocator, .window = window, .backend_type = backend_type, @@ -186,14 +184,12 @@ pub fn init(allocator: std.mem.Allocator, options: Options) !*Core { .linux_gamemode = null, }; - self.setSizeLimit(self.size_limit); + core.setSizeLimit(core.size_limit); - self.initCallbacks(); + core.initCallbacks(); if (builtin.os.tag == .linux and !options.is_app and - self.linux_gamemode == null and try activateGamemode(self.allocator)) - self.linux_gamemode = initLinuxGamemode(); - - return self; + core.linux_gamemode == null and try activateGamemode(core.allocator)) + core.linux_gamemode = initLinuxGamemode(); } fn initCallbacks(self: *Core) void { @@ -316,8 +312,6 @@ pub fn deinit(self: *Core) void { self.linux_gamemode != null and self.linux_gamemode.?) deinitLinuxGamemode(); - - self.allocator.destroy(self); } pub fn hasEvent(self: *Core) bool { diff --git a/src/platform/wasm/Core.zig b/src/platform/wasm/Core.zig index 35ef6209..5c16a2ec 100644 --- a/src/platform/wasm/Core.zig +++ b/src/platform/wasm/Core.zig @@ -25,14 +25,12 @@ id: js.CanvasId, last_cursor_position: Position, last_key_mods: KeyMods, -pub fn init(allocator: std.mem.Allocator, options: Options) !*Core { +pub fn init(core: *Core, allocator: std.mem.Allocator, options: Options) !*Core { _ = options; var selector = [1]u8{0} ** 15; const id = js.machCanvasInit(&selector[0]); - const self: *Core = try allocator.create(Core); - errdefer allocator.destroy(self); - self.* = Core{ + core.* = Core{ .allocator = allocator, .id = id, @@ -50,8 +48,6 @@ pub fn init(allocator: std.mem.Allocator, options: Options) !*Core { .num_lock = false, }, }; - - return self; } pub fn deinit(self: *Core) void {