core: con't copy App and apprt.App

Besides avoiding copying, this allows consumers to choose to allocate
these structs on the stack or to allocate on the heap. It also gives the
apprt.App a stable pointer sooner in the process.
pull/5509/head
Jeffrey C. Ollie 2025-02-01 15:10:05 -06:00 committed by Mitchell Hashimoto
parent 070e017b1b
commit c6f23bbb32
5 changed files with 25 additions and 25 deletions

View File

@ -82,28 +82,23 @@ pub const CreateError = Allocator.Error || font.SharedGridSet.InitError;
///
/// After calling this function, well behaved apprts should then call
/// `focusEvent` to set the initial focus state of the app.
pub fn create(
pub fn init(
self: *App,
alloc: Allocator,
) CreateError!*App {
var app = try alloc.create(App);
errdefer alloc.destroy(app);
) CreateError!void {
var font_grid_set = try font.SharedGridSet.init(alloc);
errdefer font_grid_set.deinit();
app.* = .{
self.* = .{
.alloc = alloc,
.surfaces = .{},
.mailbox = .{},
.font_grid_set = font_grid_set,
.config_conditional_state = .{},
};
errdefer app.surfaces.deinit(alloc);
return app;
}
pub fn destroy(self: *App) void {
pub fn deinit(self: *App) void {
// Clean up all our surfaces
for (self.surfaces.items) |surface| surface.deinit();
self.surfaces.deinit(self.alloc);
@ -114,8 +109,6 @@ pub fn destroy(self: *App) void {
// should gracefully close all surfaces.
assert(self.font_grid_set.count() == 0);
self.font_grid_set.deinit();
self.alloc.destroy(self);
}
/// Tick ticks the app loop. This will drain our mailbox and process those

View File

@ -117,10 +117,11 @@ pub const App = struct {
config: Config,
pub fn init(
self: *App,
core_app: *CoreApp,
config: *const Config,
opts: Options,
) !App {
) !void {
// We have to clone the config.
const alloc = core_app.alloc;
var config_clone = try config.clone(alloc);
@ -129,7 +130,7 @@ pub const App = struct {
var keymap = try input.Keymap.init();
errdefer keymap.deinit();
return .{
self.* = .{
.core_app = core_app,
.config = config_clone,
.opts = opts,
@ -1316,13 +1317,16 @@ pub const CAPI = struct {
opts: *const apprt.runtime.App.Options,
config: *const Config,
) !*App {
var core_app = try CoreApp.create(global.alloc);
errdefer core_app.destroy();
var core_app = try global.alloc.create(CoreApp);
errdefer {
core_app.deinit();
global.alloc.destroy(core_app);
}
// Create our runtime app
var app = try global.alloc.create(App);
errdefer global.alloc.destroy(app);
app.* = try .init(core_app, config, opts.*);
try app.init(core_app, config, opts.*);
errdefer app.terminate();
return app;
@ -1345,7 +1349,8 @@ pub const CAPI = struct {
const core_app = v.core_app;
v.terminate();
global.alloc.destroy(v);
core_app.destroy();
core_app.deinit();
global.alloc.destroy(core_app);
}
/// Update the focused state of the app.

View File

@ -50,7 +50,7 @@ pub const App = struct {
pub const Options = struct {};
pub fn init(core_app: *CoreApp, _: Options) !App {
pub fn init(self: *App, core_app: *CoreApp, _: Options) !void {
if (comptime builtin.target.os.tag.isDarwin()) {
log.warn("WARNING WARNING WARNING: GLFW ON MAC HAS BUGS.", .{});
log.warn("You should use the AppKit-based app instead. The official download", .{});
@ -107,7 +107,7 @@ pub const App = struct {
// We want the event loop to wake up instantly so we can process our tick.
glfw.postEmptyEvent();
return .{
self.* = .{
.app = core_app,
.config = config,
.darwin = darwin,

View File

@ -110,7 +110,7 @@ quit_timer: union(enum) {
expired: void,
} = .{ .off = {} },
pub fn init(core_app: *CoreApp, opts: Options) !App {
pub fn init(self: *App, core_app: *CoreApp, opts: Options) !void {
_ = opts;
// Log our GTK version
@ -424,7 +424,7 @@ pub fn init(core_app: *CoreApp, opts: Options) !App {
gtk.STYLE_PROVIDER_PRIORITY_APPLICATION + 3,
);
return .{
self.* = .{
.core_app = core_app,
.app = adw_app,
.config = config,

View File

@ -98,11 +98,13 @@ pub fn main() !MainReturn {
}
// Create our app state
var app = try App.create(alloc);
defer app.destroy();
var app: App = undefined;
defer app.deinit();
try app.init(alloc);
// Create our runtime app
var app_runtime = try apprt.App.init(app, .{});
var app_runtime: apprt.App = undefined;
try app_runtime.init(&app, .{});
defer app_runtime.terminate();
// Since - by definition - there are no surfaces when first started, the