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 <stephen@hexops.com>
This commit is contained in:
Stephen Gutekanst 2023-01-17 00:05:16 -07:00 committed by Stephen Gutekanst
parent f54d584991
commit 8082228186
4 changed files with 16 additions and 27 deletions

View file

@ -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 {

View file

@ -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);
}

View file

@ -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 {

View file

@ -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 {