diff --git a/src/gui/windows/error_prompt.zig b/src/gui/windows/error_prompt.zig index 96473633d8..f3356bd4e8 100644 --- a/src/gui/windows/error_prompt.zig +++ b/src/gui/windows/error_prompt.zig @@ -12,7 +12,10 @@ const Label = @import("../components/Label.zig"); const VerticalList = @import("../components/VerticalList.zig"); const Button = @import("../components/Button.zig"); +var overflowErrorCount: u32 = 0; +var errorText: ?[]const u8 = null; var fileExplorerIcon: Texture = undefined; +var isOpen: bool = false; pub var window = GuiWindow{ .contentSize = Vec2f{128, 64}, @@ -30,22 +33,45 @@ pub fn init() void { pub fn deinit() void { fileExplorerIcon.deinit(); + if (errorText) |text| { + main.globalAllocator.free(text); + errorText = null; + } } fn openLog() void { main.files.openDirInWindow("logs"); } -const padding: f32 = 8; -pub fn update() void { - if (main.Window.Gamepad.wereControllerMappingsDownloaded()) { - gui.closeWindowFromRef(&window); +pub fn raiseError(newText: []const u8) void { + if (isOpen) { + overflowErrorCount += 1; + onClose(); + onOpen(); + } else { + if (errorText) |text| main.globalAllocator.free(text); + errorText = main.globalAllocator.dupe(u8, newText); + overflowErrorCount = 0; + gui.openWindowFromRef(&window); } } +const padding: f32 = 8; + +const singleErrorFmtText = "#ff0000{s}"; +const multipleErrorFmtText = "#ff0000{s}\n#ffff00And {d} more...\nCheck the logs for details."; + pub fn onOpen() void { + isOpen = true; const list = VerticalList.init(.{padding, 16 + padding}, 300, 16); - list.add(Label.init(.{padding, 16 + padding}, 128, "#ffff00The game encountered errors. Check the logs for details", .center)); + var str: []const u8 = undefined; + if (overflowErrorCount == 0) { + str = std.fmt.allocPrint(main.stackAllocator.allocator, singleErrorFmtText, .{errorText.?}) catch unreachable; + } else { + str = std.fmt.allocPrint(main.stackAllocator.allocator, multipleErrorFmtText, .{errorText.?, overflowErrorCount}) catch unreachable; + } + defer main.stackAllocator.free(str); + list.add(Label.init(.{padding, 16 + padding}, 256, str, .center)); list.add(Button.initIcon(.{0, 0}, .{16, 16}, fileExplorerIcon, false, .init(openLog))); list.finish(.center); window.rootComponent = list.toComponent(); @@ -54,6 +80,7 @@ pub fn onOpen() void { } pub fn onClose() void { + isOpen = false; if (window.rootComponent) |*comp| { comp.deinit(); } diff --git a/src/main.zig b/src/main.zig index 60402ab016..966fc5e28f 100644 --- a/src/main.zig +++ b/src/main.zig @@ -87,7 +87,6 @@ fn cacheString(comptime str: []const u8) []const u8 { var logFile: ?std.Io.File = undefined; var logFileTs: ?std.Io.File = undefined; var supportsANSIColors: bool = undefined; -var openingErrorWindow: bool = false; // overwrite the log function: pub const std_options: std.Options = .{ // MARK: std_options .log_level = .debug, @@ -136,10 +135,8 @@ noinline fn runtimeLogFn(level: std.log.Level, format: []const u8, args: []const logToStdErr("[{s}]: {s}{s}", .{filePrefix, writer.buffered(), fileSuffix}); } - if (level == .err and !openingErrorWindow and !settings.launchConfig.headlessServer) { - openingErrorWindow = true; - gui.openWindow("error_prompt"); - openingErrorWindow = false; + if (level == .err and !settings.launchConfig.headlessServer) { + gui.windowlist.error_prompt.raiseError(writer.buffered()); } }