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"]
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() {
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
tracing::debug!("Starting console initialization...");
platform::get_platform().init_console().expect("Could not initialize console");
tracing::debug!("Console initialization completed");
platform.init_console().expect("Could not initialize console");
// 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);
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() {

View File

@@ -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<Option<&'static str>, 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,
};

View File

@@ -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() })
}

View File

@@ -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<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.

View File

@@ -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<()> {
let buffer_size = {
// Acquire the lock
let mut mode = self.direct_mode.lock();
// Get buffer size before flushing for debug logging
let buffer_size = self.buffered_writer.buffer_size();
// First flush any buffered content
// Flush any buffered content
self.buffered_writer.flush_to(io::stdout())?;
// Switch to direct mode
*self.direct_mode.lock() = true;
// 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(())
}