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`].
#[derive(Debug, Clone, Eq, PartialEq)]
#[derive(Clone, Eq, PartialEq)]
pub struct AudioBuffer {
spec: AudioSpec,
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 {
/// Creates and returns a new, empty, [`AudioBuffer`] that will hold audio sample data in the
/// spec/format given.

View file

@ -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<AudioChannel>,

View file

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

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
/// [`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<AudioCommand>,

View file

@ -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<U, 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> {
pub fn new() -> Self {
ComponentSystems {

View file

@ -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<EventType, ContextType> = 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<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> {
pub fn new() -> Self {
EventPublisher {
@ -51,11 +61,21 @@ impl<EventType> EventPublisher<EventType> {
///
/// 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<EventType, ContextType> {
listeners: Vec<ListenerFn<EventType, ContextType>>,
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> {
pub fn new() -> Self {
EventListeners {

View file

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

View file

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

View file

@ -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, FontError> {
BitmaskFont::load_from_bytes(&mut Cursor::new(VGA_FONT_BYTES))

View file

@ -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<ContextType> {
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> {
fn update(&mut self, state: State, context: &mut ContextType) -> Option<StateChange<ContextType>>;
fn render(&mut self, state: State, context: &mut ContextType);
@ -58,6 +70,15 @@ struct StateContainer<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> {
pub fn new(state: Box<dyn GameState<ContextType>>) -> Self {
StateContainer {
@ -163,6 +184,20 @@ pub struct States<ContextType> {
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> {
pub fn new() -> Self {
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.
///
/// [`System`]: crate::System
#[derive(Debug)]
pub struct Keyboard {
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.
///
/// [`System`]: crate::System
#[derive(Debug)]
pub struct Mouse {
x: i32,
y: i32,

View file

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