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).
|
/// this is a blocking queue so if it is full you will get errors (or block).
|
||||||
mailbox: *Mailbox,
|
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
|
/// Initialize the main app instance. This creates the main window, sets
|
||||||
/// up the renderer state, compiles the shaders, etc. This is the primary
|
/// up the renderer state, compiles the shaders, etc. This is the primary
|
||||||
/// "startup" logic.
|
/// "startup" logic.
|
||||||
@ -47,6 +50,7 @@ pub fn create(alloc: Allocator, config: *const Config) !*App {
|
|||||||
.windows = .{},
|
.windows = .{},
|
||||||
.config = config,
|
.config = config,
|
||||||
.mailbox = mailbox,
|
.mailbox = mailbox,
|
||||||
|
.quit = false,
|
||||||
};
|
};
|
||||||
errdefer app.windows.deinit(alloc);
|
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
|
/// Run the main event loop for the application. This blocks until the
|
||||||
/// application quits or every window is closed.
|
/// application quits or every window is closed.
|
||||||
pub fn run(self: *App) !void {
|
pub fn run(self: *App) !void {
|
||||||
var quit: bool = false;
|
while (!self.quit and self.windows.items.len > 0) {
|
||||||
while (!quit and self.windows.items.len > 0) {
|
|
||||||
// Block for any glfw events.
|
// Block for any glfw events.
|
||||||
try glfw.waitEvents();
|
try glfw.waitEvents();
|
||||||
|
|
||||||
@ -87,11 +90,6 @@ pub fn run(self: *App) !void {
|
|||||||
while (i < self.windows.items.len) {
|
while (i < self.windows.items.len) {
|
||||||
const window = self.windows.items[i];
|
const window = self.windows.items[i];
|
||||||
if (window.shouldClose()) {
|
if (window.shouldClose()) {
|
||||||
// If this was our final window, deinitialize the renderer
|
|
||||||
if (self.windows.items.len == 1) {
|
|
||||||
renderer.Renderer.lastWindowDeinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
window.destroy();
|
window.destroy();
|
||||||
_ = self.windows.swapRemove(i);
|
_ = self.windows.swapRemove(i);
|
||||||
continue;
|
continue;
|
||||||
@ -100,13 +98,13 @@ pub fn run(self: *App) !void {
|
|||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drain our mailbox
|
// Drain our mailbox only if we're not quitting.
|
||||||
try self.drainMailbox(&quit);
|
if (!self.quit) try self.drainMailbox();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Drain the mailbox.
|
/// Drain the mailbox.
|
||||||
fn drainMailbox(self: *App, quit: *bool) !void {
|
fn drainMailbox(self: *App) !void {
|
||||||
var drain = self.mailbox.drain();
|
var drain = self.mailbox.drain();
|
||||||
defer drain.deinit();
|
defer drain.deinit();
|
||||||
|
|
||||||
@ -114,7 +112,7 @@ fn drainMailbox(self: *App, quit: *bool) !void {
|
|||||||
log.debug("mailbox message={}", .{message});
|
log.debug("mailbox message={}", .{message});
|
||||||
switch (message) {
|
switch (message) {
|
||||||
.new_window => try self.newWindow(),
|
.new_window => try self.newWindow(),
|
||||||
.quit => quit.* = true,
|
.quit => try self.setQuit(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,10 +123,16 @@ fn newWindow(self: *App) !void {
|
|||||||
errdefer window.destroy();
|
errdefer window.destroy();
|
||||||
try self.windows.append(self.alloc, window);
|
try self.windows.append(self.alloc, window);
|
||||||
errdefer _ = self.windows.pop();
|
errdefer _ = self.windows.pop();
|
||||||
|
}
|
||||||
|
|
||||||
// This was the first window, so we need to initialize our renderer.
|
/// Start quitting
|
||||||
if (self.windows.items.len == 1) {
|
fn setQuit(self: *App) !void {
|
||||||
try window.renderer.firstWindowInit(window.window);
|
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.
|
// Add our window to the instance if it isn't set.
|
||||||
DevMode.instance.window = self;
|
DevMode.instance.window = self;
|
||||||
|
|
||||||
|
// Let our renderer setup
|
||||||
|
try renderer_impl.initDevMode(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Give the renderer one more opportunity to finalize any window
|
// Give the renderer one more opportunity to finalize any window
|
||||||
@ -427,18 +430,22 @@ pub fn destroy(self: *Window) void {
|
|||||||
self.renderer.threadEnter(self.window) catch unreachable;
|
self.renderer.threadEnter(self.window) catch unreachable;
|
||||||
self.renderer_thread.deinit();
|
self.renderer_thread.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;
|
||||||
|
|
||||||
|
// Uninitialize imgui
|
||||||
|
self.imgui_ctx.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
// Deinit our renderer
|
// Deinit our renderer
|
||||||
self.renderer.deinit();
|
self.renderer.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DevMode.enabled and DevMode.instance.window == self) {
|
|
||||||
// Clear the window
|
|
||||||
DevMode.instance.window = null;
|
|
||||||
|
|
||||||
// Uninitialize imgui
|
|
||||||
self.imgui_ctx.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// Stop our IO thread
|
// Stop our IO thread
|
||||||
self.io_thread.stop.send() catch |err|
|
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);
|
layer.setProperty("contentsScale", scaleFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is called only after the first window is opened. This may be
|
/// This is called if this renderer runs DevMode.
|
||||||
/// called multiple times if all windows are closed and a new one is
|
pub fn initDevMode(self: *const Metal, window: glfw.Window) !void {
|
||||||
/// reopened.
|
|
||||||
pub fn firstWindowInit(self: *const Metal, window: glfw.Window) !void {
|
|
||||||
if (DevMode.enabled) {
|
if (DevMode.enabled) {
|
||||||
// Initialize for our window
|
// Initialize for our window
|
||||||
assert(imgui.ImplGlfw.initForOther(
|
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.
|
/// This is called if this renderer runs DevMode.
|
||||||
pub fn lastWindowDeinit() void {
|
pub fn deinitDevMode(self: *const Metal) void {
|
||||||
|
_ = self;
|
||||||
|
|
||||||
if (DevMode.enabled) {
|
if (DevMode.enabled) {
|
||||||
imgui.ImplMetal.shutdown();
|
imgui.ImplMetal.shutdown();
|
||||||
imgui.ImplGlfw.shutdown();
|
imgui.ImplGlfw.shutdown();
|
||||||
|
@ -387,10 +387,8 @@ pub fn finalizeWindowInit(self: *const OpenGL, window: glfw.Window) !void {
|
|||||||
_ = window;
|
_ = window;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is called only after the first window is opened. This may be
|
/// This is called if this renderer runs DevMode.
|
||||||
/// called multiple times if all windows are closed and a new one is
|
pub fn initDevMode(self: *const OpenGL, window: glfw.Window) !void {
|
||||||
/// reopened.
|
|
||||||
pub fn firstWindowInit(self: *const OpenGL, window: glfw.Window) !void {
|
|
||||||
_ = self;
|
_ = self;
|
||||||
|
|
||||||
if (DevMode.enabled) {
|
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.
|
/// This is called if this renderer runs DevMode.
|
||||||
pub fn lastWindowDeinit() void {
|
pub fn deinitDevMode(self: *const OpenGL) void {
|
||||||
|
_ = self;
|
||||||
|
|
||||||
if (DevMode.enabled) {
|
if (DevMode.enabled) {
|
||||||
imgui.ImplOpenGL3.shutdown();
|
imgui.ImplOpenGL3.shutdown();
|
||||||
imgui.ImplGlfw.shutdown();
|
imgui.ImplGlfw.shutdown();
|
||||||
|
Reference in New Issue
Block a user