From 055dc85f2b12cce93e4c91a2c0290a57ae0d674a Mon Sep 17 00:00:00 2001 From: Ryan Walters Date: Tue, 2 Sep 2025 09:07:08 -0500 Subject: [PATCH] refactor: improve console handling & logs, scoped mutex lock, fix linux unused imports --- src/main.rs | 28 +++++++++++++--------------- src/platform/desktop.rs | 8 +++++++- src/platform/emscripten.rs | 4 ++++ src/platform/mod.rs | 3 +++ src/platform/tracing_buffer.rs | 23 +++++++++++++++-------- 5 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/main.rs b/src/main.rs index cf48071..889fc32 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ #![windows_subsystem = "windows"] use crate::{app::App, constants::LOOP_TIME}; -use tracing::info; +use tracing::{debug, info, warn}; mod app; mod asset; @@ -22,26 +22,24 @@ mod texture; /// This function initializes SDL, the window, the game state, and then enters /// the main game loop. pub fn main() { - // Setup buffered tracing subscriber that will buffer logs until console is ready - let switchable_writer = platform::tracing_buffer::setup_switchable_subscriber(); + let platform = platform::get_platform(); + if platform.requires_console() { + // Setup buffered tracing subscriber that will buffer logs until console is ready + let switchable_writer = platform::tracing_buffer::setup_switchable_subscriber(); - // Log early to show buffering is working - tracing::debug!("Tracing subscriber initialized with buffering - logs will be buffered until console is ready"); + // Initialize platform-specific console + platform.init_console().expect("Could not initialize console"); - // Initialize platform-specific console - tracing::debug!("Starting console initialization..."); - platform::get_platform().init_console().expect("Could not initialize console"); - tracing::debug!("Console initialization completed"); - - // Now that console is initialized, flush buffered logs and switch to direct output - tracing::debug!("Switching to direct logging mode and flushing buffer..."); - if let Err(e) = switchable_writer.switch_to_direct_mode() { - tracing::warn!("Failed to flush buffered logs to console: {}", e); + // Now that console is initialized, flush buffered logs and switch to direct output + debug!("Switching to direct logging mode and flushing buffer..."); + if let Err(error) = switchable_writer.switch_to_direct_mode() { + warn!("Failed to flush buffered logs to console: {error:?}"); + } } let mut app = App::new().expect("Could not create app"); - info!("Starting game loop ({:?})", LOOP_TIME); + info!(loop_time = ?LOOP_TIME, "Starting game loop"); loop { if !app.run() { diff --git a/src/platform/desktop.rs b/src/platform/desktop.rs index 133fe22..411c634 100644 --- a/src/platform/desktop.rs +++ b/src/platform/desktop.rs @@ -6,7 +6,6 @@ use std::time::Duration; use crate::asset::Asset; use crate::error::{AssetError, PlatformError}; use crate::platform::CommonPlatform; -use tracing::{debug, info, warn}; /// Desktop platform implementation. pub struct Platform; @@ -27,6 +26,7 @@ impl CommonPlatform for Platform { fn init_console(&self) -> Result<(), PlatformError> { #[cfg(windows)] { + use tracing::{debug, info}; use windows::Win32::System::Console::GetConsoleWindow; // Check if we already have a console window @@ -51,6 +51,10 @@ impl CommonPlatform for Platform { Ok(()) } + fn requires_console(&self) -> bool { + cfg!(windows) + } + fn get_canvas_size(&self) -> Option<(u32, u32)> { None // Desktop doesn't need this } @@ -71,6 +75,8 @@ impl CommonPlatform for Platform { impl Platform { /// Check if the output stream has been setup by a parent process fn is_output_setup() -> Result, PlatformError> { + use tracing::{debug, warn}; + use windows::Win32::Storage::FileSystem::{ GetFileType, FILE_TYPE_CHAR, FILE_TYPE_DISK, FILE_TYPE_PIPE, FILE_TYPE_REMOTE, FILE_TYPE_UNKNOWN, }; diff --git a/src/platform/emscripten.rs b/src/platform/emscripten.rs index 3bb409a..a0eb2fa 100644 --- a/src/platform/emscripten.rs +++ b/src/platform/emscripten.rs @@ -25,6 +25,10 @@ impl CommonPlatform for Platform { Ok(()) // No-op for Emscripten } + fn requires_console(&self) -> bool { + false + } + fn get_canvas_size(&self) -> Option<(u32, u32)> { Some(unsafe { get_canvas_size() }) } diff --git a/src/platform/mod.rs b/src/platform/mod.rs index c730945..aeef2f8 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -32,6 +32,9 @@ pub trait CommonPlatform { /// Loads raw asset data using the appropriate platform-specific method. fn get_asset_bytes(&self, asset: Asset) -> Result, AssetError>; + + /// Whether the platform requires a console to be initialized. + fn requires_console(&self) -> bool; } /// Returns the appropriate platform implementation based on compile-time target. diff --git a/src/platform/tracing_buffer.rs b/src/platform/tracing_buffer.rs index 8aaea86..ab8a821 100644 --- a/src/platform/tracing_buffer.rs +++ b/src/platform/tracing_buffer.rs @@ -2,7 +2,7 @@ use crate::platform::buffered_writer::BufferedWriter; use std::io; -use tracing::Level; +use tracing::{debug, Level}; use tracing_error::ErrorLayer; use tracing_subscriber::fmt::MakeWriter; use tracing_subscriber::layer::SubscriberExt; @@ -16,17 +16,24 @@ pub struct SwitchableWriter { impl SwitchableWriter { pub fn switch_to_direct_mode(&self) -> io::Result<()> { - // Get buffer size before flushing for debug logging - let buffer_size = self.buffered_writer.buffer_size(); + let buffer_size = { + // Acquire the lock + let mut mode = self.direct_mode.lock(); - // First flush any buffered content - self.buffered_writer.flush_to(io::stdout())?; + // Get buffer size before flushing for debug logging + let buffer_size = self.buffered_writer.buffer_size(); - // Switch to direct mode - *self.direct_mode.lock() = true; + // Flush any buffered content + self.buffered_writer.flush_to(io::stdout())?; + + // Switch to direct mode (and drop the lock) + *mode = true; + + buffer_size + }; // Log how much was buffered (this will now go directly to stdout) - tracing::debug!("Flushed {} bytes of buffered logs to console", buffer_size); + debug!("Flushed {buffer_size:?} bytes of buffered logs to console"); Ok(()) }