diff --git a/examples/audio_playback/src/main.rs b/examples/audio_playback/src/main.rs index 1934786..3f1d866 100644 --- a/examples/audio_playback/src/main.rs +++ b/examples/audio_playback/src/main.rs @@ -28,6 +28,7 @@ pub struct SineWaveGenerator { t: usize, } +#[allow(clippy::new_without_default)] impl SineWaveGenerator { pub fn new() -> Self { SineWaveGenerator { t: 0 } @@ -154,7 +155,7 @@ fn main() -> Result<()> { for index in 0..NUM_CHANNELS { let channel = &audio_device[index]; - let mut status = &mut statuses[index]; + let status = &mut statuses[index]; status.playing = channel.playing; status.position = channel.position; status.size = channel.data.len(); @@ -183,8 +184,7 @@ fn main() -> Result<()> { system.res.video.print_string("Audio Channels", 16, 32, FontRenderOpts::Color(14), &system.res.font); let mut y = 48; - for index in 0..NUM_CHANNELS { - let status = &statuses[index]; + for (index, status) in statuses.iter().enumerate() { system.res.video.print_string( &format!( "channel {} - {} {}", diff --git a/examples/balls/src/main.rs b/examples/balls/src/main.rs index fecd087..4fac9d1 100644 --- a/examples/balls/src/main.rs +++ b/examples/balls/src/main.rs @@ -60,8 +60,7 @@ fn main() -> Result<()> { } if system.res.keyboard.is_key_up(Scancode::S) { - for i in 0..NUM_BALLS { - let ball = &mut balls[i]; + for ball in balls.iter_mut() { ball.x += ball.dir_x; ball.y += ball.dir_y; @@ -70,11 +69,9 @@ fn main() -> Result<()> { ball.dir_x = -ball.dir_x; ball.x = 0; } - } else { - if ball.x >= (system.res.video.width() - BALL_WIDTH) as i32 { - ball.dir_x = -ball.dir_x; - ball.x = (system.res.video.width() - BALL_WIDTH) as i32; - } + } else if ball.x >= (system.res.video.width() - BALL_WIDTH) as i32 { + ball.dir_x = -ball.dir_x; + ball.x = (system.res.video.width() - BALL_WIDTH) as i32; } if ball.dir_y < 0 { @@ -82,11 +79,9 @@ fn main() -> Result<()> { ball.dir_y = -ball.dir_y; ball.y = 0; } - } else { - if ball.y >= (system.res.video.height() - BALL_HEIGHT) as i32 { - ball.dir_y = -ball.dir_y; - ball.y = (system.res.video.height() - BALL_HEIGHT) as i32; - } + } else if ball.y >= (system.res.video.height() - BALL_HEIGHT) as i32 { + ball.dir_y = -ball.dir_y; + ball.y = (system.res.video.height() - BALL_HEIGHT) as i32; } } } diff --git a/examples/balls_v2/src/entities.rs b/examples/balls_v2/src/entities.rs index 2fb10d0..1cf5c69 100644 --- a/examples/balls_v2/src/entities.rs +++ b/examples/balls_v2/src/entities.rs @@ -114,8 +114,8 @@ fn update_system_collision(context: &mut Context) { let mut velocities = context.entities.components_mut::(); for (entity, _) in bounceables.iter() { - let mut position = positions.get_mut(entity).unwrap(); - let mut velocity = velocities.get_mut(entity).unwrap(); + let position = positions.get_mut(entity).unwrap(); + let velocity = velocities.get_mut(entity).unwrap(); let mut bounced = false; if position.0.x as i32 <= 0 || position.0.x as i32 + BALL_SIZE >= context.system.res.video.right() as i32 { diff --git a/examples/imgui_integration/src/entities.rs b/examples/imgui_integration/src/entities.rs index 9928abd..37dca3e 100644 --- a/examples/imgui_integration/src/entities.rs +++ b/examples/imgui_integration/src/entities.rs @@ -369,7 +369,7 @@ pub fn remove_entity(entities: &mut Entities, entity: EntityId) { pub fn set_entity_activity(entities: &mut Entities, entity: EntityId, new_activity: EntityActivity) { let mut activities = entities.components_mut::(); - let mut activity = activities.get_mut(&entity).unwrap(); + let activity = activities.get_mut(&entity).unwrap(); // only change the activity, and more importantly, the animation if we are actually applying // an actual activity change from what it was before diff --git a/examples/imgui_integration/src/main.rs b/examples/imgui_integration/src/main.rs index a352cf9..16e8590 100644 --- a/examples/imgui_integration/src/main.rs +++ b/examples/imgui_integration/src/main.rs @@ -85,11 +85,12 @@ impl AppState for DemoState { } }); - if !ui.is_any_hovered() && !ui.is_any_focused() { - if context.core.system.res.mouse.is_button_down(MouseButton::Right) { - context.core.camera_x -= context.core.system.res.mouse.x_delta() * 2; - context.core.camera_y -= context.core.system.res.mouse.y_delta() * 2; - } + if !ui.is_any_hovered() + && !ui.is_any_focused() + && context.core.system.res.mouse.is_button_down(MouseButton::Right) + { + context.core.camera_x -= context.core.system.res.mouse.x_delta() * 2; + context.core.camera_y -= context.core.system.res.mouse.y_delta() * 2; } context.support.do_events(&mut context.core); diff --git a/examples/slimed/src/entities/systems.rs b/examples/slimed/src/entities/systems.rs index 2d45443..4ccbc5e 100644 --- a/examples/slimed/src/entities/systems.rs +++ b/examples/slimed/src/entities/systems.rs @@ -105,7 +105,7 @@ fn move_entity_with_collision( pub fn set_entity_activity(entities: &mut Entities, entity: EntityId, new_activity: EntityActivity) { let mut activities = entities.components_mut::(); - let mut activity = activities.get_mut(&entity).unwrap(); + let activity = activities.get_mut(&entity).unwrap(); // only change the activity, and more importantly, the animation if we are actually applying // an actual activity change from what it was before @@ -215,7 +215,7 @@ pub fn attack(context: &mut Core, entity: EntityId) { } } -pub fn hit_entity(context: &mut Core, target: EntityId, source: EntityId, damage: i32, damage_position: Vector2) { +pub fn hit_entity(context: &mut Core, target: EntityId, _source: EntityId, damage: i32, damage_position: Vector2) { let position; { let positions = context.entities.components::(); @@ -248,15 +248,15 @@ pub fn stop_attack(context: &mut Core, entity: EntityId) { remove_entity_attachment(&mut context.entities, entity); } -pub fn pickup(context: &mut Core, picked_up_by: EntityId, picked_up: EntityId) { - let kind; +pub fn pickup(context: &mut Core, _picked_up_by: EntityId, picked_up: EntityId) { + let _kind; let position; { let positions = context.entities.components::(); position = positions.get(&picked_up).unwrap().0; let pickupables = context.entities.components::(); - kind = pickupables.get(&picked_up).unwrap().kind; + _kind = pickupables.get(&picked_up).unwrap().kind; } // TODO: tally up the kinds @@ -332,7 +332,7 @@ fn update_system_pushing(context: &mut Core) { let pusher_bounds = bounds.get(pusher_entity).unwrap(); let pusher_circle = Circle::new(pusher_position.0.x as i32, pusher_position.0.y as i32, pusher_bounds.radius); - for (pushable_entity, pushable) in pushable.iter() { + for (pushable_entity, _pushable) in pushable.iter() { // don't push ourself ... if *pushable_entity == *pusher_entity { continue; @@ -535,7 +535,7 @@ fn update_system_randomly_spawn_slimes(context: &mut Core) { fn update_system_camera_follows_player(context: &mut Core) { if let Some((player_entity, _)) = context.entities.components::().single() { - if let Some((_, mut camera)) = context.entities.components_mut::().single_mut() { + if let Some((_, camera)) = context.entities.components_mut::().single_mut() { let positions = context.entities.components::().unwrap(); let position = positions.get(player_entity).unwrap(); @@ -569,7 +569,7 @@ fn update_system_turn_attached_entities(context: &mut Core) { // change the direction of the attachment (child) to match the parent ... if the // attachment even has a direction itself ... - if let Some(mut facing_direction) = facing_directions.get_mut(&attachment.0) { + if let Some(facing_direction) = facing_directions.get_mut(&attachment.0) { facing_direction.0 = parent_facing_direction; } } @@ -593,7 +593,7 @@ fn update_system_position_attached_entities(context: &mut Core) { } let attached_entity = attachment.0; - if let Some(mut attachment_position) = positions.get_mut(&attached_entity) { + if let Some(attachment_position) = positions.get_mut(&attached_entity) { // start off the attachment by placing it directly at the parent attachment_position.0 = parent_position; diff --git a/examples/slimed/src/states.rs b/examples/slimed/src/states.rs index 41dab3d..a3a5a70 100644 --- a/examples/slimed/src/states.rs +++ b/examples/slimed/src/states.rs @@ -43,7 +43,7 @@ impl AppState for MainMenuState { None } - fn render(&mut self, state: State, context: &mut Game) { + fn render(&mut self, _state: State, context: &mut Game) { context.core.tilemap.draw(&mut context.core.system.res.video, &context.core.tiles, 0, 0); context.support.component_systems.render(&mut context.core); @@ -83,7 +83,7 @@ impl AppState for MainMenuState { update_fade_transition(state, &mut self.fade, context.core.delta * 3.0, context) } - fn state_change(&mut self, new_state: State, old_state: State, context: &mut Game) { + fn state_change(&mut self, new_state: State, _old_state: State, context: &mut Game) { match new_state { State::Pending | State::Resume => { init_everything(context, "./assets/title_screen.map.json", 0.2, 1.0, 32); @@ -170,7 +170,7 @@ impl AppState for GamePlayState { None } - fn render(&mut self, state: State, context: &mut Game) { + fn render(&mut self, _state: State, context: &mut Game) { if let Some((_, camera)) = context.core.entities.components::().single() { context.core.tilemap.draw(&mut context.core.system.res.video, &context.core.tiles, camera.x, camera.y); } @@ -214,7 +214,7 @@ impl AppState for GamePlayState { update_fade_transition(state, &mut self.fade, context.core.delta * 3.0, context) } - fn state_change(&mut self, new_state: State, old_state: State, context: &mut Game) { + fn state_change(&mut self, new_state: State, _old_state: State, context: &mut Game) { match new_state { State::Pending => { init_everything(context, "./assets/arena.map.json", 0.5, 2.0, 100); diff --git a/examples/template_complicated/src/main.rs b/examples/template_complicated/src/main.rs index a6db873..878b640 100644 --- a/examples/template_complicated/src/main.rs +++ b/examples/template_complicated/src/main.rs @@ -108,16 +108,16 @@ impl AppState for DemoState { None } - fn render(&mut self, state: State, context: &mut App) { + fn render(&mut self, _state: State, context: &mut App) { context.core.system.res.video.clear(0); context.support.component_systems.render(&mut context.core); } - fn transition(&mut self, state: State, context: &mut App) -> bool { + fn transition(&mut self, _state: State, _context: &mut App) -> bool { true } - fn state_change(&mut self, new_state: State, old_state: State, context: &mut App) { + fn state_change(&mut self, new_state: State, _old_state: State, context: &mut App) { match new_state { State::Pending => { self.init(context); diff --git a/ggdt/Cargo.toml b/ggdt/Cargo.toml index 673c2d4..0f1db75 100644 --- a/ggdt/Cargo.toml +++ b/ggdt/Cargo.toml @@ -50,3 +50,12 @@ harness = false [[bench]] name = "triangles" harness = false + +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(recreate_ref_test_images)'] } + +[lints.clippy] +too_long_first_doc_paragraph = "allow" +tabs_in_doc_comments = "allow" # fuck off +too_many_arguments = "allow" + diff --git a/ggdt/src/audio/device.rs b/ggdt/src/audio/device.rs index 4fb7afc..fadddf0 100644 --- a/ggdt/src/audio/device.rs +++ b/ggdt/src/audio/device.rs @@ -174,6 +174,12 @@ impl AudioChannel { } } +impl Default for AudioChannel { + fn default() -> Self { + Self::new() + } +} + ////////////////////////////////////////////////////////////////////////////////////////////////// #[derive(Debug, Error)] diff --git a/ggdt/src/base/mod.rs b/ggdt/src/base/mod.rs index 32c0750..c4a71de 100644 --- a/ggdt/src/base/mod.rs +++ b/ggdt/src/base/mod.rs @@ -1,133 +1,135 @@ -//! Optional, extra types and helpers that can be used to get game's main loop boilerplate up and -//! running quicker. -//! -//! This is all of somewhat dubious quality and value at the moment. And it may continue to be this -//! way for a long while yet. And, truthfully, I suspect I may rip this out eventually. Maybe. -//! -//! The very-long-winded rationale here is that as I've started building more and more things with -//! ggdt, I started implementing games/apps using a particular pattern which I was largely -//! pushed towards due to the Rust borrow-checker (as is often the case with Rust). My games/apps -//! needed to keep their state (for clarity, the word 'state' here is being used very broadly to -//! refer to all game/app state, and not just referring to the stuff inside `ggdt::states`) -//! somewhere and my needs were a bit complicated since my game/app state often included things -//! which needed to get passed other things from inside that same "bag" of state. -//! -//! I originally wanted to do something like this, where this `App` struct is our overall "game/app -//! context" grab bag: -//! -//! ``` -//! use ggdt::prelude::*; -//! -//! pub enum Event { /* .. various events here .. */ } -//! -//! struct App { -//! pub delta: f32, -//! pub system: System, -//! pub entities: Entities, -//! pub component_systems: ComponentSystems, // oh no! :'( -//! pub event_publisher: EventPublisher, -//! pub event_listeners: EventListeners, // oh no again! :'( -//! } -//! ``` -//! -//! Of course, we cannot do this, because then we end up trying to get additional mutable borrows -//! of `App` when we eventually try to call certain methods on either the `component_systems` or -//! `event_listeners` instances. Boooo! :-( -//! -//! That of course lead me to split this structure up. I didn't and still don't like this because -//! I really don't know what to call these two things. They're both "context" and they're literally -//! only split up because of borrow-checker issues. But splitting them up did work for me. I -//! initially went with a parent-child split, which seemed logical to me at the time: -//! -//! ``` -//! use ggdt::prelude::*; -//! -//! pub enum Event { /* .. various events here .. */ } -//! -//! // "core" because what the heck else do i call this? "InnerContext"? "InnerApp"? ... -//! struct Core { -//! pub delta: f32, -//! pub system: System, -//! pub entities: Entities, -//! pub event_publisher: EventPublisher, -//! } -//! -//! // i guess this is a bit more obvious what to call it, but still ... doesn't sit right with me -//! struct App { -//! pub core: Core, -//! pub component_systems: ComponentSystems, -//! pub event_listeners: EventListeners, -//! } -//! ``` -//! -//! This structure seemed to work generally well and I've gotten pretty far with it. Keeping the -//! main `ggdt::states::States` instance _separate_ was also key, and never really a problem -//! since that can (and should) just live at the top in your main loop. Easy. -//! -//! I ended up with some common bits of code that I'd always add to projects using this structure, -//! such as a very simple copy+pasted main loop, as well as a very simple function that calculates -//! the new frame `delta` each iteration of the main loop. As well as event processing via the -//! `event_publisher` and `event_listener` instances. I also expect this set of common bits of code -//! to grow over time. And I, ideally, want a single place to put it all. -//! -//! So, this module here is my attempt at trying to formalize this a bit more and do a bit of -//! refactoring where I can keep this common copy+pasted bits somewhere. As well, I decided to -//! move away from my "context" struct having a parent-child relation for the split of the data -//! kept in these, and instead just "flatten" it out a bit (sort of) as this seems much more -//! future-proof if/when I encounter more borrow-checker issues down the road with other additions -//! to these structures. -//! -//! But again, better naming still eludes me here! -//! -//! ``` -//! use ggdt::prelude::*; -//! -//! pub enum Event { /* .. various events here .. */ } -//! -//! // "Core" because it contains the things that probably 90% of game/app code will need to work -//! // with. you'd probably want to put your game/app resources/assets on this struct too. -//! struct Core { -//! pub delta: f32, -//! pub system: System, -//! pub entities: Entities, -//! pub event_publisher: EventPublisher, -//! } -//! -//! // "Support" because it contains things that support the main/core game state? -//! // kinda grasping at straws here maybe ... -//! struct Support { -//! pub component_systems: ComponentSystems, -//! pub event_listeners: EventListeners, -//! } -//! -//! // better, maybe? -//! struct App { -//! pub core: Core, -//! pub support: Support, -//! } -//! ``` -//! -//! Even though it's another struct being added, I do like this more, despite the naming -//! uncertainty. -//! -//! So, with this being my current preferred way to architect a ggdt-using project, I created -//! some traits here in this module to formalize this all a bit more. `CoreState` and (optionally) -//! `CoreStateWithEvents` are what you'd make your project's `Core` struct (as shown in the above -//! example code) implement, while `SupportSystems` and (optionally) `SupportSystemsWithEvents` -//! are what you'd make your project's `Support` struct (again, as shown in the above example code) -//! implement. Finally, `AppContext` is for your `App` struct that contains the two. -//! -//! Once you have all this (which ironically ends up being _more_ code than if you'd not used these -//! traits ... heh), you can now optionally use the `main_loop` function to get a ready-to-use -//! main loop which is set up to use a `ggdt::states::State` state manager. -//! -//! Having said all of this ... again, I will reiterate that I don't believe any of this has reached -//! anything resembling a "good design" ... yet. There may be a good design hidden somewhere in -//! here that I've yet to fully discover, but I definitely don't think I've arrived at quite it yet. -//! -//! So, basically, I expect this to evolve over time (probably a _long_ time). And this is all -//! totally optional anyway. -//! +/*! +Optional, extra types and helpers that can be used to get game's main loop boilerplate up and +running quicker. + +This is all of somewhat dubious quality and value at the moment. And it may continue to be this +way for a long while yet. And, truthfully, I suspect I may rip this out eventually. Maybe. + +The very-long-winded rationale here is that as I've started building more and more things with +ggdt, I started implementing games/apps using a particular pattern which I was largely +pushed towards due to the Rust borrow-checker (as is often the case with Rust). My games/apps +needed to keep their state (for clarity, the word 'state' here is being used very broadly to +refer to all game/app state, and not just referring to the stuff inside `ggdt::states`) +somewhere and my needs were a bit complicated since my game/app state often included things +which needed to get passed other things from inside that same "bag" of state. + +I originally wanted to do something like this, where this `App` struct is our overall "game/app +context" grab bag: + +``` +use ggdt::prelude::*; + +pub enum Event { /* .. various events here .. */ } + +struct App { + pub delta: f32, + pub system: System, + pub entities: Entities, + pub component_systems: ComponentSystems, // oh no! :'( + pub event_publisher: EventPublisher, + pub event_listeners: EventListeners, // oh no again! :'( +} +``` + +Of course, we cannot do this, because then we end up trying to get additional mutable borrows +of `App` when we eventually try to call certain methods on either the `component_systems` or +`event_listeners` instances. Boooo! :-( + +That of course lead me to split this structure up. I didn't and still don't like this because +I really don't know what to call these two things. They're both "context" and they're literally +only split up because of borrow-checker issues. But splitting them up did work for me. I +initially went with a parent-child split, which seemed logical to me at the time: + +``` +use ggdt::prelude::*; + +pub enum Event { /* .. various events here .. */ } + +// "core" because what the heck else do i call this? "InnerContext"? "InnerApp"? ... +struct Core { + pub delta: f32, + pub system: System, + pub entities: Entities, + pub event_publisher: EventPublisher, +} + +// i guess this is a bit more obvious what to call it, but still ... doesn't sit right with me +struct App { + pub core: Core, + pub component_systems: ComponentSystems, + pub event_listeners: EventListeners, +} +``` + +This structure seemed to work generally well and I've gotten pretty far with it. Keeping the +main `ggdt::states::States` instance _separate_ was also key, and never really a problem +since that can (and should) just live at the top in your main loop. Easy. + +I ended up with some common bits of code that I'd always add to projects using this structure, +such as a very simple copy+pasted main loop, as well as a very simple function that calculates +the new frame `delta` each iteration of the main loop. As well as event processing via the +`event_publisher` and `event_listener` instances. I also expect this set of common bits of code +to grow over time. And I, ideally, want a single place to put it all. + +So, this module here is my attempt at trying to formalize this a bit more and do a bit of +refactoring where I can keep this common copy+pasted bits somewhere. As well, I decided to +move away from my "context" struct having a parent-child relation for the split of the data +kept in these, and instead just "flatten" it out a bit (sort of) as this seems much more +future-proof if/when I encounter more borrow-checker issues down the road with other additions +to these structures. + +But again, better naming still eludes me here! + +``` +use ggdt::prelude::*; + +pub enum Event { /* .. various events here .. */ } + +// "Core" because it contains the things that probably 90% of game/app code will need to work +// with. you'd probably want to put your game/app resources/assets on this struct too. +struct Core { + pub delta: f32, + pub system: System, + pub entities: Entities, + pub event_publisher: EventPublisher, +} + +// "Support" because it contains things that support the main/core game state? +// kinda grasping at straws here maybe ... +struct Support { + pub component_systems: ComponentSystems, + pub event_listeners: EventListeners, +} + +// better, maybe? +struct App { + pub core: Core, + pub support: Support, +} +``` + +Even though it's another struct being added, I do like this more, despite the naming +uncertainty. + +So, with this being my current preferred way to architect a ggdt-using project, I created +some traits here in this module to formalize this all a bit more. `CoreState` and (optionally) +`CoreStateWithEvents` are what you'd make your project's `Core` struct (as shown in the above +example code) implement, while `SupportSystems` and (optionally) `SupportSystemsWithEvents` +are what you'd make your project's `Support` struct (again, as shown in the above example code) +implement. Finally, `AppContext` is for your `App` struct that contains the two. + +Once you have all this (which ironically ends up being _more_ code than if you'd not used these +traits ... heh), you can now optionally use the `main_loop` function to get a ready-to-use +main loop which is set up to use a `ggdt::states::State` state manager. + +Having said all of this ... again, I will reiterate that I don't believe any of this has reached +anything resembling a "good design" ... yet. There may be a good design hidden somewhere in +here that I've yet to fully discover, but I definitely don't think I've arrived at quite it yet. + +So, basically, I expect this to evolve over time (probably a _long_ time). And this is all +totally optional anyway. + +*/ use thiserror::Error; diff --git a/ggdt/src/entities/mod.rs b/ggdt/src/entities/mod.rs index 0dc31db..a205071 100644 --- a/ggdt/src/entities/mod.rs +++ b/ggdt/src/entities/mod.rs @@ -230,6 +230,12 @@ impl Entities { } } +impl Default for Entities { + fn default() -> Self { + Self::new() + } +} + /////////////////////////////////////////////////////////////////////////////////////////////////// // TODO: is there some fancy way to get rid of the impl duplication here ... ? @@ -470,6 +476,12 @@ impl ComponentSystems { } } +impl Default for ComponentSystems { + fn default() -> Self { + Self::new() + } +} + /////////////////////////////////////////////////////////////////////////////////////////////////// #[cfg(test)] @@ -667,7 +679,7 @@ mod tests { // modify position components { let mut positions = em.components_mut::().unwrap(); - for mut component in positions.values_mut() { + for component in positions.values_mut() { component.0 += 5; } @@ -678,7 +690,7 @@ mod tests { // modify health components { let mut healths = em.components_mut::().unwrap(); - for mut component in healths.values_mut() { + for component in healths.values_mut() { component.0 += 5; } assert_eq!(Health(25), *healths.get(&a).unwrap()); @@ -722,10 +734,10 @@ mod tests { println!("entity {}, health: {:?}, position: {:?}", name.0, health, position); - if let Some(mut health) = health { + if let Some(health) = health { health.0 += 5; } - if let Some(mut position) = position { + if let Some(position) = position { position.0 += 5; } } diff --git a/ggdt/src/events/mod.rs b/ggdt/src/events/mod.rs index cd3bdca..1dd3679 100644 --- a/ggdt/src/events/mod.rs +++ b/ggdt/src/events/mod.rs @@ -55,6 +55,12 @@ impl EventPublisher { } } +impl Default for EventPublisher { + fn default() -> Self { + Self::new() + } +} + /// A manager for application event listeners/handlers that can dispatch events queued up by a /// [`EventPublisher`] to each of the event listeners/handlers registered with this manager. /// @@ -150,6 +156,12 @@ impl EventListeners { } } +impl Default for EventListeners { + fn default() -> Self { + Self::new() + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/ggdt/src/graphics/bitmap/blit.rs b/ggdt/src/graphics/bitmap/blit.rs index e91e9cc..fb77926 100644 --- a/ggdt/src/graphics/bitmap/blit.rs +++ b/ggdt/src/graphics/bitmap/blit.rs @@ -127,6 +127,10 @@ fn get_flipped_blit_properties( (x_inc, src_start_x, src_start_y, src_next_row_inc) } +/// # Safety +/// +/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the +/// bounds of the source and destination bitmaps. #[inline] pub unsafe fn per_pixel_blit( dest: &mut Bitmap, @@ -153,6 +157,10 @@ pub unsafe fn per_pixel_blit( } } +/// # Safety +/// +/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the +/// bounds of the source and destination bitmaps. #[inline] pub unsafe fn per_pixel_flipped_blit( dest: &mut Bitmap, @@ -183,6 +191,10 @@ pub unsafe fn per_pixel_flipped_blit( } } +/// # Safety +/// +/// Coordinates are not checked for validity, so it is up to you to ensure they lie within the +/// bounds of the source and destination bitmaps. #[inline] pub unsafe fn per_pixel_rotozoom_blit( dest: &mut Bitmap, @@ -280,6 +292,10 @@ pub unsafe fn per_pixel_rotozoom_blit( } impl Bitmap { + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn solid_blit(&mut self, src: &Self, src_region: &Rect, dest_x: i32, dest_y: i32) { let src_row_length = src_region.width as usize; let src_pitch = src.width as usize; @@ -294,6 +310,10 @@ impl Bitmap { } } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn solid_flipped_blit( &mut self, src: &Self, @@ -317,6 +337,10 @@ impl Bitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn transparent_blit( &mut self, src: &Self, @@ -339,6 +363,10 @@ impl Bitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn transparent_flipped_blit( &mut self, src: &Self, @@ -365,6 +393,10 @@ impl Bitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn transparent_single_color_blit( &mut self, src: &Self, @@ -388,6 +420,10 @@ impl Bitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn transparent_flipped_single_color_blit( &mut self, src: &Self, @@ -415,6 +451,10 @@ impl Bitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn rotozoom_blit( &mut self, src: &Self, @@ -440,6 +480,10 @@ impl Bitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn rotozoom_transparent_blit( &mut self, src: &Self, diff --git a/ggdt/src/graphics/bitmap/iff.rs b/ggdt/src/graphics/bitmap/iff.rs index 0306faf..9e570f1 100644 --- a/ggdt/src/graphics/bitmap/iff.rs +++ b/ggdt/src/graphics/bitmap/iff.rs @@ -213,7 +213,7 @@ fn merge_bitplane(plane: u32, src: &[u8], dest: &mut [u8], row_size: usize) { fn extract_bitplane(plane: u32, src: &[u8], dest: &mut [u8], row_size: usize) { let bitmask = 1 << plane; let mut src_base_index = 0; - for x in 0..row_size { + for dest_pixel in dest.iter_mut().take(row_size) { let mut data = 0; if src[src_base_index] & bitmask != 0 { data |= 128; @@ -241,7 +241,7 @@ fn extract_bitplane(plane: u32, src: &[u8], dest: &mut [u8], row_size: usize) { } src_base_index += 8; - dest[x] = data; + *dest_pixel = data; } } diff --git a/ggdt/src/graphics/bitmap/indexed/blit.rs b/ggdt/src/graphics/bitmap/indexed/blit.rs index 155edeb..cbdbd86 100644 --- a/ggdt/src/graphics/bitmap/indexed/blit.rs +++ b/ggdt/src/graphics/bitmap/indexed/blit.rs @@ -126,6 +126,10 @@ pub enum IndexedBlitMethod { } impl IndexedBitmap { + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn solid_blended_blit( &mut self, src: &Self, @@ -150,6 +154,10 @@ impl IndexedBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn solid_flipped_blended_blit( &mut self, src: &Self, @@ -178,6 +186,10 @@ impl IndexedBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn solid_palette_offset_blit( &mut self, src: &Self, @@ -198,6 +210,10 @@ impl IndexedBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn solid_flipped_palette_offset_blit( &mut self, src: &Self, @@ -222,6 +238,10 @@ impl IndexedBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn transparent_blended_blit( &mut self, src: &Self, @@ -249,6 +269,10 @@ impl IndexedBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn transparent_flipped_blended_blit( &mut self, src: &Self, @@ -280,6 +304,10 @@ impl IndexedBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn transparent_palette_offset_blit( &mut self, src: &Self, @@ -303,6 +331,10 @@ impl IndexedBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn transparent_flipped_palette_offset_blit( &mut self, src: &Self, @@ -330,6 +362,10 @@ impl IndexedBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn rotozoom_blended_blit( &mut self, src: &Self, @@ -363,6 +399,10 @@ impl IndexedBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn rotozoom_transparent_blended_blit( &mut self, src: &Self, @@ -399,6 +439,10 @@ impl IndexedBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn rotozoom_palette_offset_blit( &mut self, src: &Self, @@ -426,6 +470,10 @@ impl IndexedBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn rotozoom_transparent_palette_offset_blit( &mut self, src: &Self, @@ -522,6 +570,10 @@ impl IndexedBitmap { }; } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. #[inline] #[rustfmt::skip] pub unsafe fn blit_region_unchecked( @@ -606,12 +658,20 @@ impl IndexedBitmap { } } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. #[inline] pub unsafe fn blit_unchecked(&mut self, method: IndexedBlitMethod, src: &Self, x: i32, y: i32) { let src_region = Rect::new(0, 0, src.width, src.height); self.blit_region_unchecked(method, src, &src_region, x, y); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. #[inline] pub unsafe fn blit_atlas_unchecked( &mut self, diff --git a/ggdt/src/graphics/bitmap/indexed/primitives.rs b/ggdt/src/graphics/bitmap/indexed/primitives.rs index 39d2dda..27feca1 100644 --- a/ggdt/src/graphics/bitmap/indexed/primitives.rs +++ b/ggdt/src/graphics/bitmap/indexed/primitives.rs @@ -20,8 +20,11 @@ impl IndexedBitmap { } /// Sets the pixel at the given coordinates using a blended color via the specified blend map, - /// or using the color specified if the blend map does not include the given color. The - /// coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// or using the color specified if the blend map does not include the given color. + /// + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the /// bounds of the bitmap. #[inline] pub unsafe fn set_blended_pixel_unchecked(&mut self, x: i32, y: i32, color: u8, blend_map: &BlendMap) { diff --git a/ggdt/src/graphics/bitmap/indexed/triangles.rs b/ggdt/src/graphics/bitmap/indexed/triangles.rs index 9136f0c..d2d24d1 100644 --- a/ggdt/src/graphics/bitmap/indexed/triangles.rs +++ b/ggdt/src/graphics/bitmap/indexed/triangles.rs @@ -89,7 +89,7 @@ impl IndexedBitmap { use IndexedTriangle2d::*; match triangle { Solid { position, color } => self.solid_triangle_2d(position, *color), - SolidBlended { position, color, blendmap } => self.solid_blended_triangle_2d(position, *color, *blendmap), + SolidBlended { position, color, blendmap } => self.solid_blended_triangle_2d(position, *color, blendmap), SolidTextured { position, texcoord, bitmap } => self.solid_textured_triangle_2d(position, texcoord, bitmap), SolidTexturedBlended { position, texcoord, bitmap, blendmap } => { self.solid_textured_blended_triangle_2d(position, texcoord, bitmap, blendmap) diff --git a/ggdt/src/graphics/bitmap/mod.rs b/ggdt/src/graphics/bitmap/mod.rs index d0015eb..84eabeb 100644 --- a/ggdt/src/graphics/bitmap/mod.rs +++ b/ggdt/src/graphics/bitmap/mod.rs @@ -212,8 +212,12 @@ impl Bitmap { } /// Returns an unsafe reference to the subset of the raw pixels in this bitmap beginning at the - /// given coordinates and extending to the end of the bitmap. The coordinates are not checked - /// for validity, so it is up to you to ensure they lie within the bounds of the bitmap. + /// given coordinates and extending to the end of the bitmap. + /// + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the bitmap. #[inline] pub unsafe fn pixels_at_unchecked(&self, x: i32, y: i32) -> &[PixelType] { let offset = self.get_offset_to_xy(x, y); @@ -221,8 +225,12 @@ impl Bitmap { } /// Returns a mutable unsafe reference to the subset of the raw pixels in this bitmap beginning - /// at the given coordinates and extending to the end of the bitmap. The coordinates are not - /// checked for validity, so it is up to you to ensure they lie within the bounds of the bitmap. + /// at the given coordinates and extending to the end of the bitmap. + /// + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the bitmap. #[inline] pub unsafe fn pixels_at_mut_unchecked(&mut self, x: i32, y: i32) -> &mut [PixelType] { let offset = self.get_offset_to_xy(x, y); @@ -236,10 +244,10 @@ impl Bitmap { /// coordinates. If the coordinates given are outside the bitmap's current clipping region, /// None is returned. #[inline] - pub unsafe fn pixels_at_ptr(&self, x: i32, y: i32) -> Option<*const PixelType> { + pub fn pixels_at_ptr(&self, x: i32, y: i32) -> Option<*const PixelType> { if self.is_xy_visible(x, y) { let offset = self.get_offset_to_xy(x, y); - Some(self.pixels.as_ptr().add(offset)) + Some(unsafe { self.pixels.as_ptr().add(offset) }) } else { None } @@ -249,18 +257,22 @@ impl Bitmap { /// given coordinates. If the coordinates given are outside the bitmap's current clipping /// region, None is returned. #[inline] - pub unsafe fn pixels_at_mut_ptr(&mut self, x: i32, y: i32) -> Option<*mut PixelType> { + pub fn pixels_at_mut_ptr(&mut self, x: i32, y: i32) -> Option<*mut PixelType> { if self.is_xy_visible(x, y) { let offset = self.get_offset_to_xy(x, y); - Some(self.pixels.as_mut_ptr().add(offset)) + Some(unsafe { self.pixels.as_mut_ptr().add(offset) }) } else { None } } /// Returns an unsafe pointer to the subset of the raw pixels in this bitmap beginning at the - /// given coordinates. The coordinates are not checked for validity, so it is up to you to - /// ensure they lie within the bounds of the bitmap. + /// given coordinates. + /// + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the bitmap. #[inline] pub unsafe fn pixels_at_ptr_unchecked(&self, x: i32, y: i32) -> *const PixelType { let offset = self.get_offset_to_xy(x, y); @@ -268,8 +280,12 @@ impl Bitmap { } /// Returns a mutable unsafe pointer to the subset of the raw pixels in this bitmap beginning - /// at the given coordinates. The coordinates are not checked for validity, so it is up to you - /// to ensure they lie within the bounds of the bitmap. + /// at the given coordinates. + /// + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the bitmap. #[inline] pub unsafe fn pixels_at_mut_ptr_unchecked(&mut self, x: i32, y: i32) -> *mut PixelType { let offset = self.get_offset_to_xy(x, y); @@ -482,15 +498,15 @@ mod tests { let mut bmp = Bitmap::::new(8, 8).unwrap(); bmp.pixels_mut().copy_from_slice(RAW_BMP_PIXELS); - assert_eq!(None, unsafe { bmp.pixels_at_ptr(-1, -1) }); + assert_eq!(None, bmp.pixels_at_ptr(-1, -1)); let offset = bmp.get_offset_to_xy(1, 1); - let pixels = unsafe { bmp.pixels_at_ptr(0, 0).unwrap() }; + let pixels = bmp.pixels_at_ptr(0, 0).unwrap(); assert_eq!(0, unsafe { *pixels }); assert_eq!(1, unsafe { *(pixels.add(offset)) }); assert_eq!(2, unsafe { *(pixels.add(63)) }); - let pixels = unsafe { bmp.pixels_at_ptr(1, 1).unwrap() }; + let pixels = bmp.pixels_at_ptr(1, 1).unwrap(); assert_eq!(1, unsafe { *pixels }); assert_eq!(2, unsafe { *(pixels.add(54)) }); } @@ -500,15 +516,15 @@ mod tests { let mut bmp = Bitmap::::new(8, 8).unwrap(); bmp.pixels_mut().copy_from_slice(RAW_BMP_PIXELS); - assert_eq!(None, unsafe { bmp.pixels_at_mut_ptr(-1, -1) }); + assert_eq!(None, bmp.pixels_at_mut_ptr(-1, -1)); let offset = bmp.get_offset_to_xy(1, 1); - let pixels = unsafe { bmp.pixels_at_mut_ptr(0, 0).unwrap() }; + let pixels = bmp.pixels_at_mut_ptr(0, 0).unwrap(); assert_eq!(0, unsafe { *pixels }); assert_eq!(1, unsafe { *(pixels.add(offset)) }); assert_eq!(2, unsafe { *(pixels.add(63)) }); - let pixels = unsafe { bmp.pixels_at_mut_ptr(1, 1).unwrap() }; + let pixels = bmp.pixels_at_mut_ptr(1, 1).unwrap(); assert_eq!(1, unsafe { *pixels }); assert_eq!(2, unsafe { *(pixels.add(54)) }); } diff --git a/ggdt/src/graphics/bitmap/png.rs b/ggdt/src/graphics/bitmap/png.rs index 16e335d..7357b58 100644 --- a/ggdt/src/graphics/bitmap/png.rs +++ b/ggdt/src/graphics/bitmap/png.rs @@ -42,10 +42,10 @@ pub enum PngFormat { #[derive(Debug, Copy, Clone, Eq, PartialEq)] enum ColorFormat { Grayscale = 0, - RGB = 2, + Rgb = 2, IndexedColor = 3, GrayscaleAlpha = 4, - RGBA = 6, + Rgba = 6, } impl ColorFormat { @@ -53,10 +53,10 @@ impl ColorFormat { use ColorFormat::*; match value { 0 => Ok(Grayscale), - 2 => Ok(RGB), + 2 => Ok(Rgb), 3 => Ok(IndexedColor), 4 => Ok(GrayscaleAlpha), - 6 => Ok(RGBA), + 6 => Ok(Rgba), _ => Err(PngError::UnsupportedColorType(value)), } } @@ -202,8 +202,8 @@ impl ScanlineBuffer { pub fn new(ihdr: &ImageHeaderChunk) -> Result { let bpp = match ihdr.format { ColorFormat::IndexedColor => 1, - ColorFormat::RGB => 3, - ColorFormat::RGBA => 4, + ColorFormat::Rgb => 3, + ColorFormat::Rgba => 4, _ => return Err(PngError::BadFile(format!("Unsupported color format: {:?}", ihdr.format))), }; let stride = ihdr.width as usize * bpp; @@ -333,13 +333,13 @@ impl ScanlinePixelConverter for ScanlineBuffer { ))) } } - ColorFormat::RGB => { + ColorFormat::Rgb => { let r = self.current[offset]; let g = self.current[offset + 1]; let b = self.current[offset + 2]; Ok(RGBA::from_rgb([r, g, b])) } - ColorFormat::RGBA => { + ColorFormat::Rgba => { let r = self.current[offset]; let g = self.current[offset + 1]; let b = self.current[offset + 2]; @@ -353,13 +353,13 @@ impl ScanlinePixelConverter for ScanlineBuffer { fn write_pixel(&mut self, x: usize, pixel: RGBA) -> Result<(), PngError> { let offset = x * self.bpp; match self.format { - ColorFormat::RGB => { + ColorFormat::Rgb => { self.current[offset] = pixel.r(); self.current[offset + 1] = pixel.g(); self.current[offset + 2] = pixel.b(); Ok(()) } - ColorFormat::RGBA => { + ColorFormat::Rgba => { self.current[offset] = pixel.r(); self.current[offset + 1] = pixel.g(); self.current[offset + 2] = pixel.b(); @@ -400,8 +400,8 @@ where return Err(PngError::BadFile(String::from("Unsupported color bit depth."))); } if ihdr.format != ColorFormat::IndexedColor // . - && ihdr.format != ColorFormat::RGB - && ihdr.format != ColorFormat::RGBA + && ihdr.format != ColorFormat::Rgb + && ihdr.format != ColorFormat::Rgba { return Err(PngError::BadFile(String::from("Unsupported pixel color format."))); } @@ -593,8 +593,8 @@ impl RgbaBitmap { writer, self, match format { - PngFormat::RGB => ColorFormat::RGB, - PngFormat::RGBA => ColorFormat::RGBA, + PngFormat::RGB => ColorFormat::Rgb, + PngFormat::RGBA => ColorFormat::Rgba, }, None, ) diff --git a/ggdt/src/graphics/bitmap/primitives.rs b/ggdt/src/graphics/bitmap/primitives.rs index beb224f..712d189 100644 --- a/ggdt/src/graphics/bitmap/primitives.rs +++ b/ggdt/src/graphics/bitmap/primitives.rs @@ -31,9 +31,12 @@ impl Bitmap { } } - /// Sets the pixel at the given coordinates to the color specified. The coordinates are not - /// checked for validity, so it is up to you to ensure they lie within the bounds of the - /// bitmap. + /// Sets the pixel at the given coordinates to the color specified. + /// + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the bitmap. #[inline] pub unsafe fn set_pixel_unchecked(&mut self, x: i32, y: i32, color: PixelType) { let p = self.pixels_at_mut_ptr_unchecked(x, y); @@ -42,8 +45,12 @@ impl Bitmap { /// Sets the pixel at the given coordinates to the color returned by the given function. The /// given function is one that accepts a color value that corresponds to the current pixel at - /// the given coordinates. The coordinates are not checked for validity, so it is up to you to - /// ensure they lie within the bounds of the bitmap. + /// the given coordinates. + /// + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the bitmap. #[inline] pub unsafe fn set_custom_pixel_unchecked(&mut self, x: i32, y: i32, pixel_fn: impl Fn(PixelType) -> PixelType) { let p = self.pixels_at_mut_ptr_unchecked(x, y); @@ -57,8 +64,12 @@ impl Bitmap { self.pixels_at(x, y).map(|pixels| pixels[0]) } - /// Gets the pixel at the given coordinates. The coordinates are not checked for validity, so - /// it is up to you to ensure they lie within the bounds of the bitmap. + /// Gets the pixel at the given coordinates. + /// + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the bitmap. #[inline] pub unsafe fn get_pixel_unchecked(&self, x: i32, y: i32) -> PixelType { *(self.pixels_at_ptr_unchecked(x, y)) diff --git a/ggdt/src/graphics/bitmap/rgb/blit.rs b/ggdt/src/graphics/bitmap/rgb/blit.rs index b0f568f..7445e42 100644 --- a/ggdt/src/graphics/bitmap/rgb/blit.rs +++ b/ggdt/src/graphics/bitmap/rgb/blit.rs @@ -111,6 +111,10 @@ pub enum RgbaBlitMethod { } impl RgbaBitmap { + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn solid_tinted_blit( &mut self, src: &Self, @@ -131,6 +135,10 @@ impl RgbaBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn solid_blended_blit( &mut self, src: &Self, @@ -151,6 +159,10 @@ impl RgbaBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn solid_flipped_blended_blit( &mut self, src: &Self, @@ -175,6 +187,10 @@ impl RgbaBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn solid_flipped_tinted_blit( &mut self, src: &Self, @@ -199,6 +215,10 @@ impl RgbaBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn transparent_tinted_blit( &mut self, src: &Self, @@ -222,6 +242,10 @@ impl RgbaBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn transparent_blended_blit( &mut self, src: &Self, @@ -245,6 +269,10 @@ impl RgbaBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn transparent_flipped_tinted_blit( &mut self, src: &Self, @@ -272,6 +300,10 @@ impl RgbaBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn transparent_flipped_blended_blit( &mut self, src: &Self, @@ -299,6 +331,10 @@ impl RgbaBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn rotozoom_tinted_blit( &mut self, src: &Self, @@ -325,6 +361,10 @@ impl RgbaBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn rotozoom_blended_blit( &mut self, src: &Self, @@ -353,6 +393,10 @@ impl RgbaBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn rotozoom_transparent_tinted_blit( &mut self, src: &Self, @@ -382,6 +426,10 @@ impl RgbaBitmap { ); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. pub unsafe fn rotozoom_transparent_blended_blit( &mut self, src: &Self, @@ -479,6 +527,10 @@ impl RgbaBitmap { }; } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. #[inline] #[rustfmt::skip] pub unsafe fn blit_region_unchecked( @@ -561,12 +613,20 @@ impl RgbaBitmap { } } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. #[inline] pub unsafe fn blit_unchecked(&mut self, method: RgbaBlitMethod, src: &Self, x: i32, y: i32) { let src_region = Rect::new(0, 0, src.width, src.height); self.blit_region_unchecked(method, src, &src_region, x, y); } + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// bounds of the source and destination bitmaps. #[inline] pub unsafe fn blit_atlas_unchecked( &mut self, diff --git a/ggdt/src/graphics/bitmap/rgb/primitives.rs b/ggdt/src/graphics/bitmap/rgb/primitives.rs index 4e3bfff..14bb5bd 100644 --- a/ggdt/src/graphics/bitmap/rgb/primitives.rs +++ b/ggdt/src/graphics/bitmap/rgb/primitives.rs @@ -12,8 +12,11 @@ impl RgbaBitmap { ); } - /// Sets the pixel at the given coordinates using a blended color via the specified blend function, - /// The coordinates are not checked for validity, so it is up to you to ensure they lie within the + /// Sets the pixel at the given coordinates using a blended color via the specified blend function. + /// + /// # Safety + /// + /// Coordinates are not checked for validity, so it is up to you to ensure they lie within the /// bounds of the bitmap. #[inline] pub unsafe fn set_blended_pixel_unchecked(&mut self, x: i32, y: i32, color: RGBA, blend: BlendFunction) { diff --git a/ggdt/src/graphics/font.rs b/ggdt/src/graphics/font.rs index 9de84ad..5deff4e 100644 --- a/ggdt/src/graphics/font.rs +++ b/ggdt/src/graphics/font.rs @@ -232,8 +232,8 @@ impl BitmaskFont { } // read character widths (used for rendering) - for i in 0..NUM_CHARS { - characters[i].bounds.width = reader.read_u8()? as u32; + for character in characters.iter_mut().take(NUM_CHARS) { + character.bounds.width = reader.read_u8()? as u32; } // read global font height (used for rendering) diff --git a/ggdt/src/graphics/palette.rs b/ggdt/src/graphics/palette.rs index e071bf1..c5f256c 100644 --- a/ggdt/src/graphics/palette.rs +++ b/ggdt/src/graphics/palette.rs @@ -34,12 +34,11 @@ fn read_palette_6bit(reader: &mut T, num_colors: usize) -> Resu return Err(PaletteError::OutOfRange(num_colors)); } let mut colors = [RGBA::from_rgba([0, 0, 0, 255]); NUM_COLORS]; - for i in 0..num_colors { + for color in colors.iter_mut().take(num_colors) { let r = reader.read_u8()?; let g = reader.read_u8()?; let b = reader.read_u8()?; - let color = RGBA::from_rgb([from_6bit(r), from_6bit(g), from_6bit(b)]); - colors[i] = color; + *color = RGBA::from_rgb([from_6bit(r), from_6bit(g), from_6bit(b)]); } Ok(colors) } @@ -52,10 +51,10 @@ fn write_palette_6bit( if num_colors > NUM_COLORS { return Err(PaletteError::OutOfRange(num_colors)); } - for i in 0..num_colors { - writer.write_u8(to_6bit(colors[i].r()))?; - writer.write_u8(to_6bit(colors[i].g()))?; - writer.write_u8(to_6bit(colors[i].b()))?; + for color in colors.iter().take(num_colors) { + writer.write_u8(to_6bit(color.r()))?; + writer.write_u8(to_6bit(color.g()))?; + writer.write_u8(to_6bit(color.b()))?; } Ok(()) } @@ -66,12 +65,11 @@ fn read_palette_8bit(reader: &mut T, num_colors: usize) -> Resu return Err(PaletteError::OutOfRange(num_colors)); } let mut colors = [RGBA::from_rgba([0, 0, 0, 255]); NUM_COLORS]; - for i in 0..num_colors { + for color in colors.iter_mut().take(num_colors) { let r = reader.read_u8()?; let g = reader.read_u8()?; let b = reader.read_u8()?; - let color = RGBA::from_rgb([r, g, b]); - colors[i] = color; + *color = RGBA::from_rgb([r, g, b]); } Ok(colors) } @@ -84,10 +82,10 @@ fn write_palette_8bit( if num_colors > NUM_COLORS { return Err(PaletteError::OutOfRange(num_colors)); } - for i in 0..num_colors { - writer.write_u8(colors[i].r())?; - writer.write_u8(colors[i].g())?; - writer.write_u8(colors[i].b())?; + for color in colors.iter().take(num_colors) { + writer.write_u8(color.r())?; + writer.write_u8(color.g())?; + writer.write_u8(color.b())?; } Ok(()) } @@ -471,6 +469,12 @@ impl Palette { } } +impl Default for Palette { + fn default() -> Self { + Self::new() + } +} + impl Index for Palette { type Output = RGBA; diff --git a/ggdt/src/math/circle.rs b/ggdt/src/math/circle.rs index 8f59e6f..7bcca96 100644 --- a/ggdt/src/math/circle.rs +++ b/ggdt/src/math/circle.rs @@ -24,8 +24,7 @@ impl Circle { let mut max_x = min_x; let mut max_y = min_y; - for i in 0..points.len() { - let point = &points[i]; + for point in points.iter() { min_x = point.x.min(min_x); min_y = point.y.min(min_y); max_x = point.x.max(max_x); diff --git a/ggdt/src/states/mod.rs b/ggdt/src/states/mod.rs index 64cec48..675657b 100644 --- a/ggdt/src/states/mod.rs +++ b/ggdt/src/states/mod.rs @@ -445,6 +445,12 @@ impl States { } } +impl Default for States { + fn default() -> Self { + Self::new() + } +} + #[cfg(test)] mod tests { use claim::*; diff --git a/ggdt/src/system/input_devices/keyboard/mod.rs b/ggdt/src/system/input_devices/keyboard/mod.rs index a892759..e6ba376 100644 --- a/ggdt/src/system/input_devices/keyboard/mod.rs +++ b/ggdt/src/system/input_devices/keyboard/mod.rs @@ -55,6 +55,12 @@ impl Keyboard { } } +impl Default for Keyboard { + fn default() -> Self { + Self::new() + } +} + impl InputDevice for Keyboard { fn update(&mut self) { for state in self.keyboard.iter_mut() { diff --git a/ggdt/src/system/input_devices/mouse/cursor.rs b/ggdt/src/system/input_devices/mouse/cursor.rs index ea9a666..c3566f3 100644 --- a/ggdt/src/system/input_devices/mouse/cursor.rs +++ b/ggdt/src/system/input_devices/mouse/cursor.rs @@ -202,6 +202,16 @@ where } } +impl Default for CustomMouseCursor +where + Self: DefaultMouseCursorBitmaps, + BitmapType: GeneralBitmap, +{ + fn default() -> Self { + Self::new() + } +} + impl DefaultMouseCursorBitmaps for CustomMouseCursor { fn get_default() -> MouseCursorBitmap { #[rustfmt::skip] diff --git a/ggdt/src/system/input_devices/mouse/mod.rs b/ggdt/src/system/input_devices/mouse/mod.rs index 7702e8a..dfea3a0 100644 --- a/ggdt/src/system/input_devices/mouse/mod.rs +++ b/ggdt/src/system/input_devices/mouse/mod.rs @@ -103,6 +103,12 @@ impl Mouse { } } +impl Default for Mouse { + fn default() -> Self { + Self::new() + } +} + impl InputDevice for Mouse { fn update(&mut self) { self.x_delta = 0; diff --git a/ggdt/src/system/mod.rs b/ggdt/src/system/mod.rs index 8252efe..d790828 100644 --- a/ggdt/src/system/mod.rs +++ b/ggdt/src/system/mod.rs @@ -217,6 +217,12 @@ impl SystemBuilder { } } +impl Default for SystemBuilder { + fn default() -> Self { + Self::new() + } +} + /// Holds all primary structures necessary for interacting with the operating system and for /// applications to render to the display, react to input device events, etc. through the /// "virtual machine" exposed by this library. diff --git a/ggdt/src/utils/lzwgif.rs b/ggdt/src/utils/lzwgif.rs index 7a194e2..d506715 100644 --- a/ggdt/src/utils/lzwgif.rs +++ b/ggdt/src/utils/lzwgif.rs @@ -537,8 +537,8 @@ where // this does mean that the size of the table is always 2 less than the number of created codes. let mut table = vec![None; 1usize.wrapping_shl(MAX_BITS as u32)]; - for i in 0..initial_table_size { - table[i] = Some(vec![i as u8]); + for (i, item) in table.iter_mut().enumerate().take(initial_table_size) { + *item = Some(vec![i as u8]); } let mut max_code_value_for_bit_size = get_max_code_value_for_bits(current_bit_size); let mut next_code = initial_table_size as LzwCode + 2; diff --git a/ggdt/tests/graphics_rgba.rs b/ggdt/tests/graphics_rgba.rs index 71a1b72..b2ed8b9 100644 --- a/ggdt/tests/graphics_rgba.rs +++ b/ggdt/tests/graphics_rgba.rs @@ -2517,21 +2517,21 @@ fn get_quad( }, ], TriangleType::SolidTextured => [ - RgbaTriangle2d::SolidTextured { position: positions_1, texcoord: texcoords_1, bitmap: &texture.unwrap() }, - RgbaTriangle2d::SolidTextured { position: positions_2, texcoord: texcoords_2, bitmap: &texture.unwrap() }, + RgbaTriangle2d::SolidTextured { position: positions_1, texcoord: texcoords_1, bitmap: texture.unwrap() }, + RgbaTriangle2d::SolidTextured { position: positions_2, texcoord: texcoords_2, bitmap: texture.unwrap() }, ], TriangleType::SolidTexturedColored => [ RgbaTriangle2d::SolidTexturedColored { position: positions_1, texcoord: texcoords_1, color: single_color, - bitmap: &texture.unwrap(), + bitmap: texture.unwrap(), }, RgbaTriangle2d::SolidTexturedColored { position: positions_2, texcoord: texcoords_2, color: single_color, - bitmap: &texture.unwrap(), + bitmap: texture.unwrap(), }, ], TriangleType::SolidTexturedColoredBlended => [ @@ -2539,14 +2539,14 @@ fn get_quad( position: positions_1, texcoord: texcoords_1, color: single_color, - bitmap: &texture.unwrap(), + bitmap: texture.unwrap(), blend: BlendFunction::BlendSourceWithAlpha(128), }, RgbaTriangle2d::SolidTexturedColoredBlended { position: positions_2, texcoord: texcoords_2, color: single_color, - bitmap: &texture.unwrap(), + bitmap: texture.unwrap(), blend: BlendFunction::BlendSourceWithAlpha(128), }, ], @@ -2555,13 +2555,13 @@ fn get_quad( position: positions_1, texcoord: texcoords_1, color: colors_1, - bitmap: &texture.unwrap(), + bitmap: texture.unwrap(), }, RgbaTriangle2d::SolidTexturedMultiColored { position: positions_2, texcoord: texcoords_2, color: colors_2, - bitmap: &texture.unwrap(), + bitmap: texture.unwrap(), }, ], TriangleType::SolidTexturedMultiColoredBlended => [ @@ -2569,14 +2569,14 @@ fn get_quad( position: positions_1, texcoord: texcoords_1, color: colors_1, - bitmap: &texture.unwrap(), + bitmap: texture.unwrap(), blend: BlendFunction::BlendSourceWithAlpha(192), }, RgbaTriangle2d::SolidTexturedMultiColoredBlended { position: positions_2, texcoord: texcoords_2, color: colors_2, - bitmap: &texture.unwrap(), + bitmap: texture.unwrap(), blend: BlendFunction::BlendSourceWithAlpha(192), }, ], @@ -2584,13 +2584,13 @@ fn get_quad( RgbaTriangle2d::SolidTexturedTinted { position: positions_1, texcoord: texcoords_1, - bitmap: &texture.unwrap(), + bitmap: texture.unwrap(), tint: tint_color, }, RgbaTriangle2d::SolidTexturedTinted { position: positions_2, texcoord: texcoords_2, - bitmap: &texture.unwrap(), + bitmap: texture.unwrap(), tint: tint_color, }, ], @@ -2598,13 +2598,13 @@ fn get_quad( RgbaTriangle2d::SolidTexturedBlended { position: positions_1, texcoord: texcoords_1, - bitmap: &texture.unwrap(), + bitmap: texture.unwrap(), blend: BlendFunction::BlendSourceWithAlpha(128), }, RgbaTriangle2d::SolidTexturedBlended { position: positions_2, texcoord: texcoords_2, - bitmap: &texture.unwrap(), + bitmap: texture.unwrap(), blend: BlendFunction::BlendSourceWithAlpha(128), }, ], diff --git a/ggdt_imgui/src/lib.rs b/ggdt_imgui/src/lib.rs index 30ef7df..3c9ef33 100644 --- a/ggdt_imgui/src/lib.rs +++ b/ggdt_imgui/src/lib.rs @@ -61,6 +61,12 @@ impl ImGui { } } +impl Default for ImGui { + fn default() -> Self { + Self::new() + } +} + impl SystemEventHandler for ImGui { fn handle_event(&mut self, event: &SystemEvent) -> bool { self.platform.handle_event(&mut self.context, event) diff --git a/ggdt_imgui/src/renderer.rs b/ggdt_imgui/src/renderer.rs index 088f0af..03f0f98 100644 --- a/ggdt_imgui/src/renderer.rs +++ b/ggdt_imgui/src/renderer.rs @@ -7,7 +7,7 @@ fn create_default_texture_map(context: &mut imgui::Context) -> imgui::Texturestexture mapping for it // with imgui - let mut font = context.fonts(); + let font = context.fonts(); let mut font_atlas_texture = font.build_rgba32_texture(); font.tex_id = texture_map.insert( RgbaBitmap::from_bytes(