From 22030354016f52495726c2bedc1a89ac854eb372 Mon Sep 17 00:00:00 2001 From: gered Date: Sat, 23 Jul 2022 15:08:36 -0400 Subject: [PATCH] add a bunch of debug impls. switch some debug derives over too mainly switching #[derive(Debug)] to manual std::fmt::Debug impls to remove debug strings that would otherwise contain long strings of byte arrays which most of the time isn't so useful to see in any kind of debug logging --- libretrogd/src/audio/buffer/mod.rs | 11 ++++- libretrogd/src/audio/device.rs | 17 +++++++ libretrogd/src/audio/mod.rs | 10 ++++ libretrogd/src/audio/queue.rs | 48 +++++++++++++++++++ libretrogd/src/entities/mod.rs | 22 ++++++++- libretrogd/src/events/mod.rs | 20 ++++++++ libretrogd/src/graphics/bitmap/mod.rs | 13 ++++- libretrogd/src/graphics/blendmap.rs | 10 ++++ libretrogd/src/graphics/font.rs | 13 ++++- libretrogd/src/states/mod.rs | 35 ++++++++++++++ .../src/system/input_devices/keyboard.rs | 1 + libretrogd/src/system/input_devices/mouse.rs | 1 + libretrogd/src/system/mod.rs | 19 ++++++++ 13 files changed, 216 insertions(+), 4 deletions(-) diff --git a/libretrogd/src/audio/buffer/mod.rs b/libretrogd/src/audio/buffer/mod.rs index 567fce4..12d643e 100644 --- a/libretrogd/src/audio/buffer/mod.rs +++ b/libretrogd/src/audio/buffer/mod.rs @@ -11,12 +11,21 @@ pub enum AudioBufferError { } /// Holds audio sample data that can be played via [`AudioDevice`]. -#[derive(Debug, Clone, Eq, PartialEq)] +#[derive(Clone, Eq, PartialEq)] pub struct AudioBuffer { spec: AudioSpec, pub data: Vec, } +impl std::fmt::Debug for AudioBuffer { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("AudioBuffer") + .field("spec", &self.spec) + .field("data.len()", &self.data.len()) + .finish_non_exhaustive() + } +} + impl AudioBuffer { /// Creates and returns a new, empty, [`AudioBuffer`] that will hold audio sample data in the /// spec/format given. diff --git a/libretrogd/src/audio/device.rs b/libretrogd/src/audio/device.rs index 6abd306..89127cf 100644 --- a/libretrogd/src/audio/device.rs +++ b/libretrogd/src/audio/device.rs @@ -29,6 +29,22 @@ pub struct AudioChannel { pub position: usize, } +impl std::fmt::Debug for AudioChannel { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("AudioChannel") + .field("playing", &self.playing) + .field("loops", &self.loops) + .field("data.len()", &self.data.len()) + .field("generator", match self.generator { + Some(..) => &"Some(..)", + None => &"None", + }) + .field("volume", &self.volume) + .field("position", &self.position) + .finish_non_exhaustive() + } +} + impl AudioChannel { pub fn new() -> Self { AudioChannel { @@ -171,6 +187,7 @@ pub enum AudioDeviceError { /// Represents the audio device and performs mixing of all of the [`AudioChannel`]s that are /// currently playing. You should not be creating this manually, but obtaining it as needed via /// [`Audio::lock`]. +#[derive(Debug)] pub struct AudioDevice { spec: AudioSpec, channels: Vec, diff --git a/libretrogd/src/audio/mod.rs b/libretrogd/src/audio/mod.rs index 273cf0c..f47e3d3 100644 --- a/libretrogd/src/audio/mod.rs +++ b/libretrogd/src/audio/mod.rs @@ -1,3 +1,5 @@ +use std::fmt::Formatter; + use sdl2::audio::{AudioFormat, AudioFormatNum, AudioSpecDesired}; use sdl2::AudioSubsystem; use thiserror::Error; @@ -96,6 +98,14 @@ pub struct Audio { sdl_audio_device: sdl2::audio::AudioDevice, } +impl std::fmt::Debug for Audio { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Audio") + .field("spec", &self.spec) + .finish_non_exhaustive() + } +} + impl Audio { /// Creates a new [`Audio`] instance, wrapping the given SDL [`sdl2::audio::AudioSubsystem`]. /// The `desired_spec` given specifies the target audio playback format. diff --git a/libretrogd/src/audio/queue.rs b/libretrogd/src/audio/queue.rs index 8867ff0..11a409e 100644 --- a/libretrogd/src/audio/queue.rs +++ b/libretrogd/src/audio/queue.rs @@ -35,11 +35,59 @@ pub enum AudioCommand { }, } +impl std::fmt::Debug for AudioCommand { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + use AudioCommand::*; + match self { + StopChannel(n) => write!(f, "StopChannel({})", n), + StopAllChannels => write!(f, "StopAllChannels"), + PlayBuffer { buffer, loops } => { + f.debug_struct("PlayBuffer") + .field("buffer", buffer) + .field("loops", loops) + .finish() + }, + PlayRcBuffer { buffer, loops } => { + f.debug_struct("PlayRcBuffer") + .field("buffer", buffer) + .field("loops", loops) + .finish() + }, + PlayBufferOnChannel { channel, buffer, loops } => { + f.debug_struct("PlayBufferOnChannel") + .field("channel", channel) + .field("buffer", buffer) + .field("loops", loops) + .finish() + }, + PlayRcBufferOnChannel { channel, buffer, loops } => { + f.debug_struct("PlayRcBufferOnChannel") + .field("channel", channel) + .field("buffer", buffer) + .field("loops", loops) + .finish() + }, + PlayGenerator { loops, .. } => { + f.debug_struct("PlayGenerator") + .field("loops", loops) + .finish_non_exhaustive() + }, + PlayGeneratorOnChannel { channel, loops, .. } => { + f.debug_struct("PlayGeneratorOnChannel") + .field("channel", channel) + .field("loops", loops) + .finish_non_exhaustive() + }, + } + } +} + /// A convenience abstraction that can be used to queue up commands to be issued to an /// [`AudioDevice`]. This can be more useful to utilize in applications versus needing to directly /// lock the [`AudioDevice`] and then determine what your application needs to do and issue those /// commands that time. [`AudioQueue`] lets you play/stop audio in more of a "fire-and-forget" /// manner. +#[derive(Debug)] pub struct AudioQueue { spec: AudioSpec, commands: VecDeque, diff --git a/libretrogd/src/entities/mod.rs b/libretrogd/src/entities/mod.rs index c060923..51b76c6 100644 --- a/libretrogd/src/entities/mod.rs +++ b/libretrogd/src/entities/mod.rs @@ -1,6 +1,7 @@ -use std::any::{TypeId}; +use std::any::TypeId; use std::cell::{Ref, RefCell, RefMut}; use std::collections::{HashMap, HashSet}; +use std::fmt::Formatter; use crate::utils::AsAny; @@ -68,6 +69,16 @@ pub struct Entities { next_id: EntityId, } +impl std::fmt::Debug for Entities { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Entities") + .field("entities.len()", &self.entities.len()) + .field("component_stores.keys()", &self.component_stores.keys()) + .field("next_id", &self.next_id) + .finish_non_exhaustive() + } +} + impl Entities { /// Creates and returns a new instance of an entity manager. pub fn new() -> Self { @@ -422,6 +433,15 @@ pub struct ComponentSystems { render_systems: Vec>, } +impl std::fmt::Debug for ComponentSystems { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ComponentSystems") + .field("update_systems.len()", &self.update_systems.len()) + .field("render_systems.len()", &self.render_systems.len()) + .finish_non_exhaustive() + } +} + impl ComponentSystems { pub fn new() -> Self { ComponentSystems { diff --git a/libretrogd/src/events/mod.rs b/libretrogd/src/events/mod.rs index 0513397..646b6e7 100644 --- a/libretrogd/src/events/mod.rs +++ b/libretrogd/src/events/mod.rs @@ -1,4 +1,5 @@ use std::collections::VecDeque; +use std::fmt::Formatter; /// An event listener/handler function that returns true if it handled the event and no other /// listeners/handlers should be called next with the same event, or false if the event was not @@ -7,10 +8,19 @@ pub type ListenerFn = fn(event: &EventType, &mut Context /// An event publisher that code can use to queue up events to be handled by an [`EventListeners`] /// instance. The `EventType` here should usually be an application-specific "events" enum. +#[derive(Clone)] pub struct EventPublisher { queue: VecDeque, } +impl std::fmt::Debug for EventPublisher { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("EventPublisher") + .field("queue.len()", &self.queue.len()) + .finish_non_exhaustive() + } +} + impl EventPublisher { pub fn new() -> Self { EventPublisher { @@ -51,11 +61,21 @@ impl EventPublisher { /// /// The `ContextType` specified here should be some application-specific context type that you /// want available in all of your event listener/handler functions. +#[derive(Clone)] pub struct EventListeners { listeners: Vec>, dispatch_queue: VecDeque, } +impl std::fmt::Debug for EventListeners { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("EventListeners") + .field("listeners.len()", &self.listeners.len()) + .field("dispatch_queue.len()", &self.dispatch_queue.len()) + .finish_non_exhaustive() + } +} + impl EventListeners { pub fn new() -> Self { EventListeners { diff --git a/libretrogd/src/graphics/bitmap/mod.rs b/libretrogd/src/graphics/bitmap/mod.rs index 734d977..26bae50 100644 --- a/libretrogd/src/graphics/bitmap/mod.rs +++ b/libretrogd/src/graphics/bitmap/mod.rs @@ -1,3 +1,4 @@ +use std::fmt::Formatter; use std::path::Path; use std::slice; @@ -40,7 +41,7 @@ pub enum BitmapError { /// one row to the next is always exactly equal to the bitmap width. Rendering operations provided /// here are done with respect to the bitmaps clipping region, where rendering outside of the /// clipping region is simply not performed / stops at the clipping boundary. -#[derive(Debug, Clone, Eq, PartialEq)] +#[derive(Clone, Eq, PartialEq)] pub struct Bitmap { width: u32, height: u32, @@ -48,6 +49,16 @@ pub struct Bitmap { clip_region: Rect, } +impl std::fmt::Debug for Bitmap { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Bitmap") + .field("width", &self.width) + .field("height", &self.height) + .field("clip_region", &self.clip_region) + .finish_non_exhaustive() + } +} + impl Bitmap { /// Creates a new Bitmap with the specified dimensions. /// diff --git a/libretrogd/src/graphics/blendmap.rs b/libretrogd/src/graphics/blendmap.rs index a9c7b59..2e8c5ce 100644 --- a/libretrogd/src/graphics/blendmap.rs +++ b/libretrogd/src/graphics/blendmap.rs @@ -1,3 +1,4 @@ +use std::fmt::Formatter; use std::fs::File; use std::io::{BufReader, BufWriter}; use std::path::Path; @@ -43,6 +44,15 @@ pub struct BlendMap { mapping: Box<[BlendMapping]>, } +impl std::fmt::Debug for BlendMap { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("BlendMap") + .field("start_color", &self.start_color) + .field("end_color", &self.end_color) + .finish_non_exhaustive() + } +} + impl BlendMap { /// Creates and returns a new [`BlendMap`] with source color mappings for the given inclusive /// range only. The `start_color` and `end_color` may also be equal to create a blend map with diff --git a/libretrogd/src/graphics/font.rs b/libretrogd/src/graphics/font.rs index dd6bad5..b159775 100644 --- a/libretrogd/src/graphics/font.rs +++ b/libretrogd/src/graphics/font.rs @@ -1,3 +1,4 @@ +use std::fmt::Formatter; use std::fs::File; use std::io::{BufReader, BufWriter, Cursor}; use std::path::Path; @@ -83,13 +84,23 @@ impl Character for BitmaskCharacter { } } -#[derive(Debug, Clone, Eq, PartialEq)] +#[derive(Clone, Eq, PartialEq)] pub struct BitmaskFont { characters: Box<[BitmaskCharacter]>, line_height: u8, space_width: u8, } +impl std::fmt::Debug for BitmaskFont { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("BitmaskFont") + .field("line_height", &self.line_height) + .field("space_width", &self.space_width) + .field("characters.len()", &self.characters.len()) + .finish() + } +} + impl BitmaskFont { pub fn new_vga_font() -> Result { BitmaskFont::load_from_bytes(&mut Cursor::new(VGA_FONT_BYTES)) diff --git a/libretrogd/src/states/mod.rs b/libretrogd/src/states/mod.rs index 025ae37..d2f01b1 100644 --- a/libretrogd/src/states/mod.rs +++ b/libretrogd/src/states/mod.rs @@ -1,4 +1,5 @@ use std::collections::VecDeque; +use std::fmt::Formatter; use std::ops::DerefMut; use thiserror::Error; @@ -34,6 +35,17 @@ pub enum StateChange { Pop(u32), } +impl std::fmt::Debug for StateChange { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + use StateChange::*; + match *self { + Push(..) => write!(f, "Push"), + Swap(..) => write!(f, "Swap"), + Pop(n) => write!(f, "Pop({})", n), + } + } +} + pub trait GameState { fn update(&mut self, state: State, context: &mut ContextType) -> Option>; fn render(&mut self, state: State, context: &mut ContextType); @@ -58,6 +70,15 @@ struct StateContainer { state: Box>, } +impl std::fmt::Debug for StateContainer { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("StateContainer") + .field("current_state", &self.current_state) + .field("pending_state_change", &self.pending_state_change) + .finish_non_exhaustive() + } +} + impl StateContainer { pub fn new(state: Box>) -> Self { StateContainer { @@ -163,6 +184,20 @@ pub struct States { pop_count: Option, } +impl std::fmt::Debug for States { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("States") + .field("states", &self.states) + .field("command", &self.command) + .field("pending_state", match self.pending_state { + Some(..) => &"Some(..)", + None => &"None", + }) + .field("pop_count", &self.pop_count) + .finish_non_exhaustive() + } +} + impl States { pub fn new() -> Self { States { diff --git a/libretrogd/src/system/input_devices/keyboard.rs b/libretrogd/src/system/input_devices/keyboard.rs index 1e94158..9f0a2d4 100644 --- a/libretrogd/src/system/input_devices/keyboard.rs +++ b/libretrogd/src/system/input_devices/keyboard.rs @@ -12,6 +12,7 @@ const MAX_KEYS: usize = 256; /// this house-keeping by simply calling [`System`]'s `do_events` method once per frame. /// /// [`System`]: crate::System +#[derive(Debug)] pub struct Keyboard { keyboard: [ButtonState; MAX_KEYS], // Box<[ButtonState]>, } diff --git a/libretrogd/src/system/input_devices/mouse.rs b/libretrogd/src/system/input_devices/mouse.rs index 26b0b4c..081c605 100644 --- a/libretrogd/src/system/input_devices/mouse.rs +++ b/libretrogd/src/system/input_devices/mouse.rs @@ -39,6 +39,7 @@ const DEFAULT_MOUSE_CURSOR: [u8; DEFAULT_MOUSE_CURSOR_WIDTH * DEFAULT_MOUSE_CURS /// this house-keeping by simply calling [`System`]'s `do_events` method once per frame. /// /// [`System`]: crate::System +#[derive(Debug)] pub struct Mouse { x: i32, y: i32, diff --git a/libretrogd/src/system/mod.rs b/libretrogd/src/system/mod.rs index 93dcf8f..6f8dcd3 100644 --- a/libretrogd/src/system/mod.rs +++ b/libretrogd/src/system/mod.rs @@ -1,3 +1,5 @@ +use std::fmt::Formatter; + use byte_slice_cast::AsByteSlice; use sdl2::{AudioSubsystem, EventPump, Sdl, TimerSubsystem, VideoSubsystem}; use sdl2::audio::AudioSpecDesired; @@ -333,6 +335,23 @@ pub struct System { pub mouse: Mouse, } +impl std::fmt::Debug for System { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("System") + .field("audio", &self.audio) + .field("audio_queue", &self.audio_queue) + .field("video", &self.video) + .field("palette", &self.palette) + .field("font", &self.font) + .field("keyboard", &self.keyboard) + .field("mouse", &self.mouse) + .field("target_framerate", &self.target_framerate) + .field("target_framerate_delta", &self.target_framerate_delta) + .field("next_tick", &self.next_tick) + .finish_non_exhaustive() + } +} + impl System { /// Takes the `video` backbuffer bitmap and `palette` and renders it to the window, up-scaled /// to fill the window (preserving aspect ratio of course). If V-sync is enabled, this method