refactor: improve console handling & logs, scoped mutex lock, fix linux unused imports

This commit is contained in:
Ryan Walters
2025-09-02 09:07:08 -05:00
parent 39a5df1ffd
commit 055dc85f2b
5 changed files with 42 additions and 24 deletions

View File

@@ -2,7 +2,7 @@
#![windows_subsystem = "windows"] #![windows_subsystem = "windows"]
use crate::{app::App, constants::LOOP_TIME}; use crate::{app::App, constants::LOOP_TIME};
use tracing::info; use tracing::{debug, info, warn};
mod app; mod app;
mod asset; mod asset;
@@ -22,26 +22,24 @@ mod texture;
/// This function initializes SDL, the window, the game state, and then enters /// This function initializes SDL, the window, the game state, and then enters
/// the main game loop. /// the main game loop.
pub fn main() { pub fn main() {
let platform = platform::get_platform();
if platform.requires_console() {
// Setup buffered tracing subscriber that will buffer logs until console is ready // Setup buffered tracing subscriber that will buffer logs until console is ready
let switchable_writer = platform::tracing_buffer::setup_switchable_subscriber(); 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 // Initialize platform-specific console
tracing::debug!("Starting console initialization..."); platform.init_console().expect("Could not initialize console");
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 // Now that console is initialized, flush buffered logs and switch to direct output
tracing::debug!("Switching to direct logging mode and flushing buffer..."); debug!("Switching to direct logging mode and flushing buffer...");
if let Err(e) = switchable_writer.switch_to_direct_mode() { if let Err(error) = switchable_writer.switch_to_direct_mode() {
tracing::warn!("Failed to flush buffered logs to console: {}", e); warn!("Failed to flush buffered logs to console: {error:?}");
}
} }
let mut app = App::new().expect("Could not create app"); 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 { loop {
if !app.run() { if !app.run() {

View File

@@ -6,7 +6,6 @@ use std::time::Duration;
use crate::asset::Asset; use crate::asset::Asset;
use crate::error::{AssetError, PlatformError}; use crate::error::{AssetError, PlatformError};
use crate::platform::CommonPlatform; use crate::platform::CommonPlatform;
use tracing::{debug, info, warn};
/// Desktop platform implementation. /// Desktop platform implementation.
pub struct Platform; pub struct Platform;
@@ -27,6 +26,7 @@ impl CommonPlatform for Platform {
fn init_console(&self) -> Result<(), PlatformError> { fn init_console(&self) -> Result<(), PlatformError> {
#[cfg(windows)] #[cfg(windows)]
{ {
use tracing::{debug, info};
use windows::Win32::System::Console::GetConsoleWindow; use windows::Win32::System::Console::GetConsoleWindow;
// Check if we already have a console window // Check if we already have a console window
@@ -51,6 +51,10 @@ impl CommonPlatform for Platform {
Ok(()) Ok(())
} }
fn requires_console(&self) -> bool {
cfg!(windows)
}
fn get_canvas_size(&self) -> Option<(u32, u32)> { fn get_canvas_size(&self) -> Option<(u32, u32)> {
None // Desktop doesn't need this None // Desktop doesn't need this
} }
@@ -71,6 +75,8 @@ impl CommonPlatform for Platform {
impl Platform { impl Platform {
/// Check if the output stream has been setup by a parent process /// Check if the output stream has been setup by a parent process
fn is_output_setup() -> Result<Option<&'static str>, PlatformError> { fn is_output_setup() -> Result<Option<&'static str>, PlatformError> {
use tracing::{debug, warn};
use windows::Win32::Storage::FileSystem::{ use windows::Win32::Storage::FileSystem::{
GetFileType, FILE_TYPE_CHAR, FILE_TYPE_DISK, FILE_TYPE_PIPE, FILE_TYPE_REMOTE, FILE_TYPE_UNKNOWN, GetFileType, FILE_TYPE_CHAR, FILE_TYPE_DISK, FILE_TYPE_PIPE, FILE_TYPE_REMOTE, FILE_TYPE_UNKNOWN,
}; };

View File

@@ -25,6 +25,10 @@ impl CommonPlatform for Platform {
Ok(()) // No-op for Emscripten Ok(()) // No-op for Emscripten
} }
fn requires_console(&self) -> bool {
false
}
fn get_canvas_size(&self) -> Option<(u32, u32)> { fn get_canvas_size(&self) -> Option<(u32, u32)> {
Some(unsafe { get_canvas_size() }) Some(unsafe { get_canvas_size() })
} }

View File

@@ -32,6 +32,9 @@ pub trait CommonPlatform {
/// Loads raw asset data using the appropriate platform-specific method. /// Loads raw asset data using the appropriate platform-specific method.
fn get_asset_bytes(&self, asset: Asset) -> Result<Cow<'static, [u8]>, AssetError>; fn get_asset_bytes(&self, asset: Asset) -> Result<Cow<'static, [u8]>, 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. /// Returns the appropriate platform implementation based on compile-time target.

View File

@@ -2,7 +2,7 @@
use crate::platform::buffered_writer::BufferedWriter; use crate::platform::buffered_writer::BufferedWriter;
use std::io; use std::io;
use tracing::Level; use tracing::{debug, Level};
use tracing_error::ErrorLayer; use tracing_error::ErrorLayer;
use tracing_subscriber::fmt::MakeWriter; use tracing_subscriber::fmt::MakeWriter;
use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::layer::SubscriberExt;
@@ -16,17 +16,24 @@ pub struct SwitchableWriter {
impl SwitchableWriter { impl SwitchableWriter {
pub fn switch_to_direct_mode(&self) -> io::Result<()> { pub fn switch_to_direct_mode(&self) -> io::Result<()> {
let buffer_size = {
// Acquire the lock
let mut mode = self.direct_mode.lock();
// Get buffer size before flushing for debug logging // Get buffer size before flushing for debug logging
let buffer_size = self.buffered_writer.buffer_size(); let buffer_size = self.buffered_writer.buffer_size();
// First flush any buffered content // Flush any buffered content
self.buffered_writer.flush_to(io::stdout())?; self.buffered_writer.flush_to(io::stdout())?;
// Switch to direct mode // Switch to direct mode (and drop the lock)
*self.direct_mode.lock() = true; *mode = true;
buffer_size
};
// Log how much was buffered (this will now go directly to stdout) // 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(()) Ok(())
} }