mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
Deinit devmode more cleanly
This commit is contained in:
32
src/App.zig
32
src/App.zig
@ -32,6 +32,9 @@ config: *const Config,
|
||||
/// this is a blocking queue so if it is full you will get errors (or block).
|
||||
mailbox: *Mailbox,
|
||||
|
||||
/// Set to true once we're quitting. This never goes false again.
|
||||
quit: bool,
|
||||
|
||||
/// Initialize the main app instance. This creates the main window, sets
|
||||
/// up the renderer state, compiles the shaders, etc. This is the primary
|
||||
/// "startup" logic.
|
||||
@ -47,6 +50,7 @@ pub fn create(alloc: Allocator, config: *const Config) !*App {
|
||||
.windows = .{},
|
||||
.config = config,
|
||||
.mailbox = mailbox,
|
||||
.quit = false,
|
||||
};
|
||||
errdefer app.windows.deinit(alloc);
|
||||
|
||||
@ -74,8 +78,7 @@ pub fn wakeup(self: App) void {
|
||||
/// Run the main event loop for the application. This blocks until the
|
||||
/// application quits or every window is closed.
|
||||
pub fn run(self: *App) !void {
|
||||
var quit: bool = false;
|
||||
while (!quit and self.windows.items.len > 0) {
|
||||
while (!self.quit and self.windows.items.len > 0) {
|
||||
// Block for any glfw events.
|
||||
try glfw.waitEvents();
|
||||
|
||||
@ -87,11 +90,6 @@ pub fn run(self: *App) !void {
|
||||
while (i < self.windows.items.len) {
|
||||
const window = self.windows.items[i];
|
||||
if (window.shouldClose()) {
|
||||
// If this was our final window, deinitialize the renderer
|
||||
if (self.windows.items.len == 1) {
|
||||
renderer.Renderer.lastWindowDeinit();
|
||||
}
|
||||
|
||||
window.destroy();
|
||||
_ = self.windows.swapRemove(i);
|
||||
continue;
|
||||
@ -100,13 +98,13 @@ pub fn run(self: *App) !void {
|
||||
i += 1;
|
||||
}
|
||||
|
||||
// Drain our mailbox
|
||||
try self.drainMailbox(&quit);
|
||||
// Drain our mailbox only if we're not quitting.
|
||||
if (!self.quit) try self.drainMailbox();
|
||||
}
|
||||
}
|
||||
|
||||
/// Drain the mailbox.
|
||||
fn drainMailbox(self: *App, quit: *bool) !void {
|
||||
fn drainMailbox(self: *App) !void {
|
||||
var drain = self.mailbox.drain();
|
||||
defer drain.deinit();
|
||||
|
||||
@ -114,7 +112,7 @@ fn drainMailbox(self: *App, quit: *bool) !void {
|
||||
log.debug("mailbox message={}", .{message});
|
||||
switch (message) {
|
||||
.new_window => try self.newWindow(),
|
||||
.quit => quit.* = true,
|
||||
.quit => try self.setQuit(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -125,10 +123,16 @@ fn newWindow(self: *App) !void {
|
||||
errdefer window.destroy();
|
||||
try self.windows.append(self.alloc, window);
|
||||
errdefer _ = self.windows.pop();
|
||||
}
|
||||
|
||||
// This was the first window, so we need to initialize our renderer.
|
||||
if (self.windows.items.len == 1) {
|
||||
try window.renderer.firstWindowInit(window.window);
|
||||
/// Start quitting
|
||||
fn setQuit(self: *App) !void {
|
||||
if (self.quit) return;
|
||||
self.quit = true;
|
||||
|
||||
// Mark that all our windows should close
|
||||
for (self.windows.items) |window| {
|
||||
window.window.setShouldClose(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -393,6 +393,9 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window {
|
||||
|
||||
// Add our window to the instance if it isn't set.
|
||||
DevMode.instance.window = self;
|
||||
|
||||
// Let our renderer setup
|
||||
try renderer_impl.initDevMode(window);
|
||||
}
|
||||
|
||||
// Give the renderer one more opportunity to finalize any window
|
||||
@ -427,11 +430,11 @@ pub fn destroy(self: *Window) void {
|
||||
self.renderer.threadEnter(self.window) catch unreachable;
|
||||
self.renderer_thread.deinit();
|
||||
|
||||
// Deinit our renderer
|
||||
self.renderer.deinit();
|
||||
}
|
||||
|
||||
// If we are devmode-owning, clean that up.
|
||||
if (DevMode.enabled and DevMode.instance.window == self) {
|
||||
// Let our renderer clean up
|
||||
self.renderer.deinitDevMode();
|
||||
|
||||
// Clear the window
|
||||
DevMode.instance.window = null;
|
||||
|
||||
@ -439,6 +442,10 @@ pub fn destroy(self: *Window) void {
|
||||
self.imgui_ctx.destroy();
|
||||
}
|
||||
|
||||
// Deinit our renderer
|
||||
self.renderer.deinit();
|
||||
}
|
||||
|
||||
{
|
||||
// Stop our IO thread
|
||||
self.io_thread.stop.send() catch |err|
|
||||
|
@ -265,10 +265,8 @@ pub fn finalizeWindowInit(self: *const Metal, window: glfw.Window) !void {
|
||||
layer.setProperty("contentsScale", scaleFactor);
|
||||
}
|
||||
|
||||
/// This is called only after the first window is opened. This may be
|
||||
/// called multiple times if all windows are closed and a new one is
|
||||
/// reopened.
|
||||
pub fn firstWindowInit(self: *const Metal, window: glfw.Window) !void {
|
||||
/// This is called if this renderer runs DevMode.
|
||||
pub fn initDevMode(self: *const Metal, window: glfw.Window) !void {
|
||||
if (DevMode.enabled) {
|
||||
// Initialize for our window
|
||||
assert(imgui.ImplGlfw.initForOther(
|
||||
@ -279,8 +277,10 @@ pub fn firstWindowInit(self: *const Metal, window: glfw.Window) !void {
|
||||
}
|
||||
}
|
||||
|
||||
/// This is called only when the last window is destroyed.
|
||||
pub fn lastWindowDeinit() void {
|
||||
/// This is called if this renderer runs DevMode.
|
||||
pub fn deinitDevMode(self: *const Metal) void {
|
||||
_ = self;
|
||||
|
||||
if (DevMode.enabled) {
|
||||
imgui.ImplMetal.shutdown();
|
||||
imgui.ImplGlfw.shutdown();
|
||||
|
@ -387,10 +387,8 @@ pub fn finalizeWindowInit(self: *const OpenGL, window: glfw.Window) !void {
|
||||
_ = window;
|
||||
}
|
||||
|
||||
/// This is called only after the first window is opened. This may be
|
||||
/// called multiple times if all windows are closed and a new one is
|
||||
/// reopened.
|
||||
pub fn firstWindowInit(self: *const OpenGL, window: glfw.Window) !void {
|
||||
/// This is called if this renderer runs DevMode.
|
||||
pub fn initDevMode(self: *const OpenGL, window: glfw.Window) !void {
|
||||
_ = self;
|
||||
|
||||
if (DevMode.enabled) {
|
||||
@ -403,8 +401,10 @@ pub fn firstWindowInit(self: *const OpenGL, window: glfw.Window) !void {
|
||||
}
|
||||
}
|
||||
|
||||
/// This is called only when the last window is destroyed.
|
||||
pub fn lastWindowDeinit() void {
|
||||
/// This is called if this renderer runs DevMode.
|
||||
pub fn deinitDevMode(self: *const OpenGL) void {
|
||||
_ = self;
|
||||
|
||||
if (DevMode.enabled) {
|
||||
imgui.ImplOpenGL3.shutdown();
|
||||
imgui.ImplGlfw.shutdown();
|
||||
|
Reference in New Issue
Block a user