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
This commit is contained in:
Gered 2022-07-23 15:08:36 -04:00
parent cf02471aa8
commit 2203035401
13 changed files with 216 additions and 4 deletions

View file

@ -11,12 +11,21 @@ pub enum AudioBufferError {
} }
/// Holds audio sample data that can be played via [`AudioDevice`]. /// Holds audio sample data that can be played via [`AudioDevice`].
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Clone, Eq, PartialEq)]
pub struct AudioBuffer { pub struct AudioBuffer {
spec: AudioSpec, spec: AudioSpec,
pub data: Vec<u8>, pub data: Vec<u8>,
} }
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 { impl AudioBuffer {
/// Creates and returns a new, empty, [`AudioBuffer`] that will hold audio sample data in the /// Creates and returns a new, empty, [`AudioBuffer`] that will hold audio sample data in the
/// spec/format given. /// spec/format given.

View file

@ -29,6 +29,22 @@ pub struct AudioChannel {
pub position: usize, 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 { impl AudioChannel {
pub fn new() -> Self { pub fn new() -> Self {
AudioChannel { AudioChannel {
@ -171,6 +187,7 @@ pub enum AudioDeviceError {
/// Represents the audio device and performs mixing of all of the [`AudioChannel`]s that are /// 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 /// currently playing. You should not be creating this manually, but obtaining it as needed via
/// [`Audio::lock`]. /// [`Audio::lock`].
#[derive(Debug)]
pub struct AudioDevice { pub struct AudioDevice {
spec: AudioSpec, spec: AudioSpec,
channels: Vec<AudioChannel>, channels: Vec<AudioChannel>,

View file

@ -1,3 +1,5 @@
use std::fmt::Formatter;
use sdl2::audio::{AudioFormat, AudioFormatNum, AudioSpecDesired}; use sdl2::audio::{AudioFormat, AudioFormatNum, AudioSpecDesired};
use sdl2::AudioSubsystem; use sdl2::AudioSubsystem;
use thiserror::Error; use thiserror::Error;
@ -96,6 +98,14 @@ pub struct Audio {
sdl_audio_device: sdl2::audio::AudioDevice<AudioDevice>, sdl_audio_device: sdl2::audio::AudioDevice<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 { impl Audio {
/// Creates a new [`Audio`] instance, wrapping the given SDL [`sdl2::audio::AudioSubsystem`]. /// Creates a new [`Audio`] instance, wrapping the given SDL [`sdl2::audio::AudioSubsystem`].
/// The `desired_spec` given specifies the target audio playback format. /// The `desired_spec` given specifies the target audio playback format.

View file

@ -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 /// 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 /// [`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 /// 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" /// commands that time. [`AudioQueue`] lets you play/stop audio in more of a "fire-and-forget"
/// manner. /// manner.
#[derive(Debug)]
pub struct AudioQueue { pub struct AudioQueue {
spec: AudioSpec, spec: AudioSpec,
commands: VecDeque<AudioCommand>, commands: VecDeque<AudioCommand>,

View file

@ -1,6 +1,7 @@
use std::any::{TypeId}; use std::any::TypeId;
use std::cell::{Ref, RefCell, RefMut}; use std::cell::{Ref, RefCell, RefMut};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::fmt::Formatter;
use crate::utils::AsAny; use crate::utils::AsAny;
@ -68,6 +69,16 @@ pub struct Entities {
next_id: EntityId, 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 { impl Entities {
/// Creates and returns a new instance of an entity manager. /// Creates and returns a new instance of an entity manager.
pub fn new() -> Self { pub fn new() -> Self {
@ -422,6 +433,15 @@ pub struct ComponentSystems<U, R> {
render_systems: Vec<RenderFn<R>>, render_systems: Vec<RenderFn<R>>,
} }
impl<U, R> std::fmt::Debug for ComponentSystems<U, R> {
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<U, R> ComponentSystems<U, R> { impl<U, R> ComponentSystems<U, R> {
pub fn new() -> Self { pub fn new() -> Self {
ComponentSystems { ComponentSystems {

View file

@ -1,4 +1,5 @@
use std::collections::VecDeque; use std::collections::VecDeque;
use std::fmt::Formatter;
/// An event listener/handler function that returns true if it handled the event and no other /// 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 /// listeners/handlers should be called next with the same event, or false if the event was not
@ -7,10 +8,19 @@ pub type ListenerFn<EventType, ContextType> = fn(event: &EventType, &mut Context
/// An event publisher that code can use to queue up events to be handled by an [`EventListeners`] /// 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. /// instance. The `EventType` here should usually be an application-specific "events" enum.
#[derive(Clone)]
pub struct EventPublisher<EventType> { pub struct EventPublisher<EventType> {
queue: VecDeque<EventType>, queue: VecDeque<EventType>,
} }
impl<EventType> std::fmt::Debug for EventPublisher<EventType> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("EventPublisher")
.field("queue.len()", &self.queue.len())
.finish_non_exhaustive()
}
}
impl<EventType> EventPublisher<EventType> { impl<EventType> EventPublisher<EventType> {
pub fn new() -> Self { pub fn new() -> Self {
EventPublisher { EventPublisher {
@ -51,11 +61,21 @@ impl<EventType> EventPublisher<EventType> {
/// ///
/// The `ContextType` specified here should be some application-specific context type that you /// The `ContextType` specified here should be some application-specific context type that you
/// want available in all of your event listener/handler functions. /// want available in all of your event listener/handler functions.
#[derive(Clone)]
pub struct EventListeners<EventType, ContextType> { pub struct EventListeners<EventType, ContextType> {
listeners: Vec<ListenerFn<EventType, ContextType>>, listeners: Vec<ListenerFn<EventType, ContextType>>,
dispatch_queue: VecDeque<EventType>, dispatch_queue: VecDeque<EventType>,
} }
impl<EventType, ContextType> std::fmt::Debug for EventListeners<EventType, ContextType> {
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<EventType, ContextType> EventListeners<EventType, ContextType> { impl<EventType, ContextType> EventListeners<EventType, ContextType> {
pub fn new() -> Self { pub fn new() -> Self {
EventListeners { EventListeners {

View file

@ -1,3 +1,4 @@
use std::fmt::Formatter;
use std::path::Path; use std::path::Path;
use std::slice; 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 /// 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 /// 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. /// clipping region is simply not performed / stops at the clipping boundary.
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Clone, Eq, PartialEq)]
pub struct Bitmap { pub struct Bitmap {
width: u32, width: u32,
height: u32, height: u32,
@ -48,6 +49,16 @@ pub struct Bitmap {
clip_region: Rect, 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 { impl Bitmap {
/// Creates a new Bitmap with the specified dimensions. /// Creates a new Bitmap with the specified dimensions.
/// ///

View file

@ -1,3 +1,4 @@
use std::fmt::Formatter;
use std::fs::File; use std::fs::File;
use std::io::{BufReader, BufWriter}; use std::io::{BufReader, BufWriter};
use std::path::Path; use std::path::Path;
@ -43,6 +44,15 @@ pub struct BlendMap {
mapping: Box<[BlendMapping]>, 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 { impl BlendMap {
/// Creates and returns a new [`BlendMap`] with source color mappings for the given inclusive /// 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 /// range only. The `start_color` and `end_color` may also be equal to create a blend map with

View file

@ -1,3 +1,4 @@
use std::fmt::Formatter;
use std::fs::File; use std::fs::File;
use std::io::{BufReader, BufWriter, Cursor}; use std::io::{BufReader, BufWriter, Cursor};
use std::path::Path; use std::path::Path;
@ -83,13 +84,23 @@ impl Character for BitmaskCharacter {
} }
} }
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Clone, Eq, PartialEq)]
pub struct BitmaskFont { pub struct BitmaskFont {
characters: Box<[BitmaskCharacter]>, characters: Box<[BitmaskCharacter]>,
line_height: u8, line_height: u8,
space_width: 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 { impl BitmaskFont {
pub fn new_vga_font() -> Result<BitmaskFont, FontError> { pub fn new_vga_font() -> Result<BitmaskFont, FontError> {
BitmaskFont::load_from_bytes(&mut Cursor::new(VGA_FONT_BYTES)) BitmaskFont::load_from_bytes(&mut Cursor::new(VGA_FONT_BYTES))

View file

@ -1,4 +1,5 @@
use std::collections::VecDeque; use std::collections::VecDeque;
use std::fmt::Formatter;
use std::ops::DerefMut; use std::ops::DerefMut;
use thiserror::Error; use thiserror::Error;
@ -34,6 +35,17 @@ pub enum StateChange<ContextType> {
Pop(u32), Pop(u32),
} }
impl<ContextType> std::fmt::Debug for StateChange<ContextType> {
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<ContextType> { pub trait GameState<ContextType> {
fn update(&mut self, state: State, context: &mut ContextType) -> Option<StateChange<ContextType>>; fn update(&mut self, state: State, context: &mut ContextType) -> Option<StateChange<ContextType>>;
fn render(&mut self, state: State, context: &mut ContextType); fn render(&mut self, state: State, context: &mut ContextType);
@ -58,6 +70,15 @@ struct StateContainer<ContextType> {
state: Box<dyn GameState<ContextType>>, state: Box<dyn GameState<ContextType>>,
} }
impl<ContextType> std::fmt::Debug for StateContainer<ContextType> {
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<ContextType> StateContainer<ContextType> { impl<ContextType> StateContainer<ContextType> {
pub fn new(state: Box<dyn GameState<ContextType>>) -> Self { pub fn new(state: Box<dyn GameState<ContextType>>) -> Self {
StateContainer { StateContainer {
@ -163,6 +184,20 @@ pub struct States<ContextType> {
pop_count: Option<u32>, pop_count: Option<u32>,
} }
impl<ContextType> std::fmt::Debug for States<ContextType> {
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<ContextType> States<ContextType> { impl<ContextType> States<ContextType> {
pub fn new() -> Self { pub fn new() -> Self {
States { States {

View file

@ -12,6 +12,7 @@ const MAX_KEYS: usize = 256;
/// this house-keeping by simply calling [`System`]'s `do_events` method once per frame. /// this house-keeping by simply calling [`System`]'s `do_events` method once per frame.
/// ///
/// [`System`]: crate::System /// [`System`]: crate::System
#[derive(Debug)]
pub struct Keyboard { pub struct Keyboard {
keyboard: [ButtonState; MAX_KEYS], // Box<[ButtonState]>, keyboard: [ButtonState; MAX_KEYS], // Box<[ButtonState]>,
} }

View file

@ -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. /// this house-keeping by simply calling [`System`]'s `do_events` method once per frame.
/// ///
/// [`System`]: crate::System /// [`System`]: crate::System
#[derive(Debug)]
pub struct Mouse { pub struct Mouse {
x: i32, x: i32,
y: i32, y: i32,

View file

@ -1,3 +1,5 @@
use std::fmt::Formatter;
use byte_slice_cast::AsByteSlice; use byte_slice_cast::AsByteSlice;
use sdl2::{AudioSubsystem, EventPump, Sdl, TimerSubsystem, VideoSubsystem}; use sdl2::{AudioSubsystem, EventPump, Sdl, TimerSubsystem, VideoSubsystem};
use sdl2::audio::AudioSpecDesired; use sdl2::audio::AudioSpecDesired;
@ -333,6 +335,23 @@ pub struct System {
pub mouse: Mouse, 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 { impl System {
/// Takes the `video` backbuffer bitmap and `palette` and renders it to the window, up-scaled /// 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 /// to fill the window (preserving aspect ratio of course). If V-sync is enabled, this method