From fc39be8bb0e1af9088bcb5c44660ef6afc823bf7 Mon Sep 17 00:00:00 2001 From: james7132 Date: Thu, 5 Jan 2023 16:59:30 -0800 Subject: [PATCH 1/3] Use let-else on Options --- crates/bevy_animation/src/lib.rs | 7 +- crates/bevy_app/src/plugin_group.rs | 23 +-- crates/bevy_app/src/schedule_runner.rs | 5 +- crates/bevy_asset/src/asset_server.rs | 25 +-- crates/bevy_asset/src/debug_asset_server.rs | 8 +- crates/bevy_asset/src/io/file_asset_io.rs | 43 ++-- crates/bevy_audio/src/audio_output.rs | 5 +- crates/bevy_core_pipeline/src/bloom/mod.rs | 192 +++++++++--------- crates/bevy_core_pipeline/src/core_3d/mod.rs | 53 +++-- crates/bevy_diagnostic/src/diagnostic.rs | 6 +- .../src/log_diagnostics_plugin.rs | 45 ++-- crates/bevy_ecs/src/schedule/run_criteria.rs | 26 +-- crates/bevy_ecs/src/storage/blob_vec.rs | 19 +- crates/bevy_ecs/src/storage/sparse_set.rs | 33 ++- crates/bevy_ecs/src/system/commands/mod.rs | 19 +- crates/bevy_ecs/src/world/entity_ref.rs | 20 +- crates/bevy_ecs/src/world/mod.rs | 18 +- crates/bevy_gltf/src/loader.rs | 34 ++-- crates/bevy_hierarchy/src/child_builder.rs | 94 +++++---- crates/bevy_hierarchy/src/hierarchy.rs | 7 +- crates/bevy_log/src/android_tracing.rs | 17 +- crates/bevy_pbr/src/light.rs | 100 +++++---- crates/bevy_pbr/src/material.rs | 113 +++++------ crates/bevy_pbr/src/render/light.rs | 84 ++++---- crates/bevy_pbr/src/render/mesh.rs | 105 +++++----- crates/bevy_pbr/src/wireframe.rs | 45 ++-- .../bevy_reflect_derive/src/documentation.rs | 7 +- .../src/field_attributes.rs | 11 +- crates/bevy_reflect/src/impls/std.rs | 43 ++-- crates/bevy_reflect/src/path.rs | 84 ++++---- crates/bevy_reflect/src/serde/de.rs | 3 +- crates/bevy_reflect/src/struct_trait.rs | 13 +- crates/bevy_reflect/src/tuple_struct.rs | 5 +- crates/bevy_render/src/extract_resource.rs | 10 +- crates/bevy_render/src/mesh/mesh/mod.rs | 20 +- .../bevy_render/src/render_graph/context.rs | 21 +- crates/bevy_render/src/render_graph/graph.rs | 64 +++--- .../src/render_phase/draw_state.rs | 20 +- crates/bevy_render/src/render_phase/mod.rs | 25 ++- .../src/render_resource/buffer_vec.rs | 9 +- .../src/render_resource/pipeline_cache.rs | 51 ++--- .../src/render_resource/resource_macros.rs | 39 ++-- .../bevy_render/src/render_resource/shader.rs | 22 +- .../bevy_render/src/renderer/graph_runner.rs | 28 ++- crates/bevy_render/src/renderer/mod.rs | 8 +- crates/bevy_render/src/view/mod.rs | 147 +++++++------- crates/bevy_render/src/view/visibility/mod.rs | 27 ++- .../bevy_scene/src/dynamic_scene_builder.rs | 11 +- crates/bevy_scene/src/scene_spawner.rs | 54 +++-- .../src/dynamic_texture_atlas_builder.rs | 16 +- crates/bevy_sprite/src/mesh2d/material.rs | 78 ++++--- crates/bevy_sprite/src/mesh2d/mesh.rs | 23 +-- crates/bevy_text/src/font_atlas.rs | 18 +- crates/bevy_text/src/glyph_brush.rs | 83 ++++---- crates/bevy_time/src/fixed_timestep.rs | 19 +- crates/bevy_ui/src/focus.rs | 16 +- crates/bevy_ui/src/render/mod.rs | 130 ++++++------ crates/bevy_ui/src/widget/image.rs | 19 +- crates/bevy_ui/src/widget/text.rs | 9 +- crates/bevy_utils/src/label.rs | 9 +- crates/bevy_window/src/windows.rs | 8 +- examples/2d/mesh2d_manual.rs | 42 ++-- examples/3d/skybox.rs | 7 +- examples/async_tasks/async_compute.rs | 23 +-- examples/audio/audio_control.rs | 11 +- examples/games/alien_cake_addict.rs | 12 +- examples/games/breakout.rs | 62 +++--- examples/shader/shader_instancing.rs | 24 +-- .../tools/scene_viewer/scene_viewer_plugin.rs | 15 +- examples/ui/font_atlas_debug.rs | 46 ++--- examples/ui/text.rs | 10 +- tools/spancmp/src/main.rs | 8 +- 72 files changed, 1197 insertions(+), 1359 deletions(-) diff --git a/crates/bevy_animation/src/lib.rs b/crates/bevy_animation/src/lib.rs index 9b9e8de991af9..2c8e5f6502725 100644 --- a/crates/bevy_animation/src/lib.rs +++ b/crates/bevy_animation/src/lib.rs @@ -263,11 +263,8 @@ fn verify_no_ancestor_player( if maybe_player.is_some() { return false; } - if let Some(parent) = parent { - current = parent.get(); - } else { - return true; - } + let Some(parent) = parent else { return true }; + current = parent.get(); } } diff --git a/crates/bevy_app/src/plugin_group.rs b/crates/bevy_app/src/plugin_group.rs index d5c7be8dcb602..e2f0561a58f76 100644 --- a/crates/bevy_app/src/plugin_group.rs +++ b/crates/bevy_app/src/plugin_group.rs @@ -174,18 +174,17 @@ impl PluginGroupBuilder { /// Panics if one of the plugin in the group was already added to the application. pub fn finish(mut self, app: &mut App) { for ty in &self.order { - if let Some(entry) = self.plugins.remove(ty) { - if entry.enabled { - debug!("added plugin: {}", entry.plugin.name()); - if let Err(AppError::DuplicatePlugin { plugin_name }) = - app.add_boxed_plugin(entry.plugin) - { - panic!( - "Error adding plugin {} in group {}: plugin was already added in application", - plugin_name, - self.group_name - ); - } + let Some(entry) = self.plugins.remove(ty) else { continue }; + if entry.enabled { + debug!("added plugin: {}", entry.plugin.name()); + if let Err(AppError::DuplicatePlugin { plugin_name }) = + app.add_boxed_plugin(entry.plugin) + { + panic!( + "Error adding plugin {} in group {}: plugin was already added in application", + plugin_name, + self.group_name + ); } } } diff --git a/crates/bevy_app/src/schedule_runner.rs b/crates/bevy_app/src/schedule_runner.rs index 04535c045dd9d..a777b27ee9d73 100644 --- a/crates/bevy_app/src/schedule_runner.rs +++ b/crates/bevy_app/src/schedule_runner.rs @@ -117,9 +117,8 @@ impl Plugin for ScheduleRunnerPlugin { #[cfg(not(target_arch = "wasm32"))] { while let Ok(delay) = tick(&mut app, wait) { - if let Some(delay) = delay { - std::thread::sleep(delay); - } + let Some(delay) = delay else { continue }; + std::thread::sleep(delay); } } diff --git a/crates/bevy_asset/src/asset_server.rs b/crates/bevy_asset/src/asset_server.rs index 97c3ede26e623..54fabc6c68480 100644 --- a/crates/bevy_asset/src/asset_server.rs +++ b/crates/bevy_asset/src/asset_server.rs @@ -512,20 +512,17 @@ impl AssetServer { let asset_sources = self.server.asset_sources.read(); let asset_lifecycles = self.server.asset_lifecycles.read(); for potential_free in potential_frees.drain(..) { - if let Some(&0) = ref_counts.get(&potential_free) { - let type_uuid = match potential_free { - HandleId::Id(type_uuid, _) => Some(type_uuid), - HandleId::AssetPathId(id) => asset_sources - .get(&id.source_path_id()) - .and_then(|source_info| source_info.get_asset_type(id.label_id())), - }; - - if let Some(type_uuid) = type_uuid { - if let Some(asset_lifecycle) = asset_lifecycles.get(&type_uuid) { - asset_lifecycle.free_asset(potential_free); - } - } - } + let Some(&0) = ref_counts.get(&potential_free) else { continue }; + let type_uuid = match potential_free { + HandleId::Id(type_uuid, _) => Some(type_uuid), + HandleId::AssetPathId(id) => asset_sources + .get(&id.source_path_id()) + .and_then(|source_info| source_info.get_asset_type(id.label_id())), + }; + + let Some(type_uuid) = type_uuid else { continue } ; + let Some(asset_lifecycle) = asset_lifecycles.get(&type_uuid) else { continue }; + asset_lifecycle.free_asset(potential_free); } } } diff --git a/crates/bevy_asset/src/debug_asset_server.rs b/crates/bevy_asset/src/debug_asset_server.rs index 690dd6769dc7c..66a4a739db2c5 100644 --- a/crates/bevy_asset/src/debug_asset_server.rs +++ b/crates/bevy_asset/src/debug_asset_server.rs @@ -103,11 +103,9 @@ pub(crate) fn sync_debug_assets( AssetEvent::Created { handle } | AssetEvent::Modified { handle } => handle, AssetEvent::Removed { .. } => continue, }; - if let Some(handle) = handle_map.handles.get(debug_handle) { - if let Some(debug_asset) = debug_assets.get(debug_handle) { - assets.set_untracked(handle, debug_asset.clone()); - } - } + let Some(handle) = handle_map.handles.get(debug_handle) else { continue }; + let Some(debug_asset) = debug_assets.get(debug_handle) else { continue }; + assets.set_untracked(handle, debug_asset.clone()); } } diff --git a/crates/bevy_asset/src/io/file_asset_io.rs b/crates/bevy_asset/src/io/file_asset_io.rs index 59447dfac5031..2320159633831 100644 --- a/crates/bevy_asset/src/io/file_asset_io.rs +++ b/crates/bevy_asset/src/io/file_asset_io.rs @@ -166,34 +166,27 @@ impl AssetIo for FileAssetIo { ))] pub fn filesystem_watcher_system(asset_server: Res) { let mut changed = HashSet::default(); - let asset_io = - if let Some(asset_io) = asset_server.server.asset_io.downcast_ref::() { - asset_io - } else { - return; + let Some(asset_io) = asset_server.server.asset_io.downcast_ref::() else { return }; + let Some(ref watcher) = *asset_io.filesystem_watcher.read() else { return }; + loop { + let event = match watcher.receiver.try_recv() { + Ok(result) => result.unwrap(), + Err(TryRecvError::Empty) => break, + Err(TryRecvError::Disconnected) => panic!("FilesystemWatcher disconnected."), }; - let watcher = asset_io.filesystem_watcher.read(); - if let Some(ref watcher) = *watcher { - loop { - let event = match watcher.receiver.try_recv() { - Ok(result) => result.unwrap(), - Err(TryRecvError::Empty) => break, - Err(TryRecvError::Disconnected) => panic!("FilesystemWatcher disconnected."), - }; - if let notify::event::Event { - kind: notify::event::EventKind::Modify(_), - paths, - .. - } = event - { - for path in &paths { - if !changed.contains(path) { - let relative_path = path.strip_prefix(&asset_io.root_path).unwrap(); - let _ = asset_server.load_untracked(relative_path.into(), true); - } + if let notify::event::Event { + kind: notify::event::EventKind::Modify(_), + paths, + .. + } = event + { + for path in &paths { + if !changed.contains(path) { + let relative_path = path.strip_prefix(&asset_io.root_path).unwrap(); + let _ = asset_server.load_untracked(relative_path.into(), true); } - changed.extend(paths); } + changed.extend(paths); } } } diff --git a/crates/bevy_audio/src/audio_output.rs b/crates/bevy_audio/src/audio_output.rs index 31ee5f503adc3..d6f1b826b258f 100644 --- a/crates/bevy_audio/src/audio_output.rs +++ b/crates/bevy_audio/src/audio_output.rs @@ -100,9 +100,8 @@ pub fn play_queued_audio_system( mut audio: ResMut>, mut sinks: ResMut>, ) { - if let Some(audio_sources) = audio_sources { - audio_output.try_play_queued(&*audio_sources, &mut *audio, &mut sinks); - }; + let Some(audio_sources) = audio_sources else { return }; + audio_output.try_play_queued(&*audio_sources, &mut *audio, &mut sinks); } /// Asset controlling the playback of a sound diff --git a/crates/bevy_core_pipeline/src/bloom/mod.rs b/crates/bevy_core_pipeline/src/bloom/mod.rs index 0700c3b16b3ae..1132ed8acd690 100644 --- a/crates/bevy_core_pipeline/src/bloom/mod.rs +++ b/crates/bevy_core_pipeline/src/bloom/mod.rs @@ -638,15 +638,41 @@ fn queue_bloom_bind_groups( uniforms: Res>, views: Query<(Entity, &ViewTarget, &BloomTextures)>, ) { - if let Some(uniforms) = uniforms.binding() { - for (entity, view_target, textures) in &views { - let prefilter_bind_group = render_device.create_bind_group(&BindGroupDescriptor { - label: Some("bloom_prefilter_bind_group"), + let Some(uniforms) = uniforms.binding() else { return }; + for (entity, view_target, textures) in &views { + let prefilter_bind_group = render_device.create_bind_group(&BindGroupDescriptor { + label: Some("bloom_prefilter_bind_group"), + layout: &pipelines.downsampling_bind_group_layout, + entries: &[ + BindGroupEntry { + binding: 0, + resource: BindingResource::TextureView(view_target.main_texture()), + }, + BindGroupEntry { + binding: 1, + resource: BindingResource::Sampler(&pipelines.sampler), + }, + BindGroupEntry { + binding: 2, + resource: uniforms.clone(), + }, + ], + }); + + let bind_group_count = textures.mip_count as usize - 1; + + let mut downsampling_bind_groups = Vec::with_capacity(bind_group_count); + for mip in 1..textures.mip_count { + let bind_group = render_device.create_bind_group(&BindGroupDescriptor { + label: Some("bloom_downsampling_bind_group"), layout: &pipelines.downsampling_bind_group_layout, entries: &[ BindGroupEntry { binding: 0, - resource: BindingResource::TextureView(view_target.main_texture()), + resource: BindingResource::TextureView(&BloomTextures::texture_view( + &textures.texture_a, + mip - 1, + )), }, BindGroupEntry { binding: 1, @@ -659,103 +685,75 @@ fn queue_bloom_bind_groups( ], }); - let bind_group_count = textures.mip_count as usize - 1; - - let mut downsampling_bind_groups = Vec::with_capacity(bind_group_count); - for mip in 1..textures.mip_count { - let bind_group = render_device.create_bind_group(&BindGroupDescriptor { - label: Some("bloom_downsampling_bind_group"), - layout: &pipelines.downsampling_bind_group_layout, - entries: &[ - BindGroupEntry { - binding: 0, - resource: BindingResource::TextureView(&BloomTextures::texture_view( - &textures.texture_a, - mip - 1, - )), - }, - BindGroupEntry { - binding: 1, - resource: BindingResource::Sampler(&pipelines.sampler), - }, - BindGroupEntry { - binding: 2, - resource: uniforms.clone(), - }, - ], - }); + downsampling_bind_groups.push(bind_group); + } - downsampling_bind_groups.push(bind_group); - } + let mut upsampling_bind_groups = Vec::with_capacity(bind_group_count); + for mip in 1..textures.mip_count { + let up = BloomTextures::texture_view(&textures.texture_a, mip - 1); + let org = BloomTextures::texture_view( + if mip == textures.mip_count - 1 { + &textures.texture_a + } else { + &textures.texture_b + }, + mip, + ); - let mut upsampling_bind_groups = Vec::with_capacity(bind_group_count); - for mip in 1..textures.mip_count { - let up = BloomTextures::texture_view(&textures.texture_a, mip - 1); - let org = BloomTextures::texture_view( - if mip == textures.mip_count - 1 { - &textures.texture_a - } else { - &textures.texture_b + let bind_group = render_device.create_bind_group(&BindGroupDescriptor { + label: Some("bloom_upsampling_bind_group"), + layout: &pipelines.upsampling_bind_group_layout, + entries: &[ + BindGroupEntry { + binding: 0, + resource: BindingResource::TextureView(&org), }, - mip, - ); - - let bind_group = render_device.create_bind_group(&BindGroupDescriptor { - label: Some("bloom_upsampling_bind_group"), - layout: &pipelines.upsampling_bind_group_layout, - entries: &[ - BindGroupEntry { - binding: 0, - resource: BindingResource::TextureView(&org), - }, - BindGroupEntry { - binding: 1, - resource: BindingResource::Sampler(&pipelines.sampler), - }, - BindGroupEntry { - binding: 2, - resource: uniforms.clone(), - }, - BindGroupEntry { - binding: 3, - resource: BindingResource::TextureView(&up), - }, - ], - }); - - upsampling_bind_groups.push(bind_group); - } - - let upsampling_final_bind_group = - render_device.create_bind_group(&BindGroupDescriptor { - label: Some("bloom_upsampling_final_bind_group"), - layout: &pipelines.downsampling_bind_group_layout, - entries: &[ - BindGroupEntry { - binding: 0, - resource: BindingResource::TextureView(&BloomTextures::texture_view( - &textures.texture_b, - 0, - )), - }, - BindGroupEntry { - binding: 1, - resource: BindingResource::Sampler(&pipelines.sampler), - }, - BindGroupEntry { - binding: 2, - resource: uniforms.clone(), - }, - ], - }); - - commands.entity(entity).insert(BloomBindGroups { - prefilter_bind_group, - downsampling_bind_groups: downsampling_bind_groups.into_boxed_slice(), - upsampling_bind_groups: upsampling_bind_groups.into_boxed_slice(), - upsampling_final_bind_group, + BindGroupEntry { + binding: 1, + resource: BindingResource::Sampler(&pipelines.sampler), + }, + BindGroupEntry { + binding: 2, + resource: uniforms.clone(), + }, + BindGroupEntry { + binding: 3, + resource: BindingResource::TextureView(&up), + }, + ], }); + + upsampling_bind_groups.push(bind_group); } + + let upsampling_final_bind_group = render_device.create_bind_group(&BindGroupDescriptor { + label: Some("bloom_upsampling_final_bind_group"), + layout: &pipelines.downsampling_bind_group_layout, + entries: &[ + BindGroupEntry { + binding: 0, + resource: BindingResource::TextureView(&BloomTextures::texture_view( + &textures.texture_b, + 0, + )), + }, + BindGroupEntry { + binding: 1, + resource: BindingResource::Sampler(&pipelines.sampler), + }, + BindGroupEntry { + binding: 2, + resource: uniforms.clone(), + }, + ], + }); + + commands.entity(entity).insert(BloomBindGroups { + prefilter_bind_group, + downsampling_bind_groups: downsampling_bind_groups.into_boxed_slice(), + upsampling_bind_groups: upsampling_bind_groups.into_boxed_slice(), + upsampling_final_bind_group, + }); } } diff --git a/crates/bevy_core_pipeline/src/core_3d/mod.rs b/crates/bevy_core_pipeline/src/core_3d/mod.rs index 34a430a345398..f6eba2c859df6 100644 --- a/crates/bevy_core_pipeline/src/core_3d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/mod.rs @@ -263,33 +263,32 @@ pub fn prepare_core_3d_depth_textures( ) { let mut textures = HashMap::default(); for (entity, camera) in &views_3d { - if let Some(physical_target_size) = camera.physical_target_size { - let cached_texture = textures - .entry(camera.target.clone()) - .or_insert_with(|| { - texture_cache.get( - &render_device, - TextureDescriptor { - label: Some("view_depth_texture"), - size: Extent3d { - depth_or_array_layers: 1, - width: physical_target_size.x, - height: physical_target_size.y, - }, - mip_level_count: 1, - sample_count: msaa.samples, - dimension: TextureDimension::D2, - format: TextureFormat::Depth32Float, /* PERF: vulkan docs recommend using 24 - * bit depth for better performance */ - usage: TextureUsages::RENDER_ATTACHMENT, + let Some(physical_target_size) = camera.physical_target_size else { continue }; + let cached_texture = textures + .entry(camera.target.clone()) + .or_insert_with(|| { + texture_cache.get( + &render_device, + TextureDescriptor { + label: Some("view_depth_texture"), + size: Extent3d { + depth_or_array_layers: 1, + width: physical_target_size.x, + height: physical_target_size.y, }, - ) - }) - .clone(); - commands.entity(entity).insert(ViewDepthTexture { - texture: cached_texture.texture, - view: cached_texture.default_view, - }); - } + mip_level_count: 1, + sample_count: msaa.samples, + dimension: TextureDimension::D2, + format: TextureFormat::Depth32Float, /* PERF: vulkan docs recommend using 24 + * bit depth for better performance */ + usage: TextureUsages::RENDER_ATTACHMENT, + }, + ) + }) + .clone(); + commands.entity(entity).insert(ViewDepthTexture { + texture: cached_texture.texture, + view: cached_texture.default_view, + }); } } diff --git a/crates/bevy_diagnostic/src/diagnostic.rs b/crates/bevy_diagnostic/src/diagnostic.rs index 7d947359db3c3..73b5214fda689 100644 --- a/crates/bevy_diagnostic/src/diagnostic.rs +++ b/crates/bevy_diagnostic/src/diagnostic.rs @@ -169,10 +169,8 @@ impl Diagnostic { return None; } - if let Some(newest) = self.history.back() { - if let Some(oldest) = self.history.front() { - return Some(newest.time.duration_since(oldest.time)); - } + if let (Some(newest), Some(oldest)) = (self.history.back(), self.history.front()) { + return Some(newest.time.duration_since(oldest.time)); } None diff --git a/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs b/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs index c0a06238396ed..e99bd6344c725 100644 --- a/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs +++ b/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs @@ -53,31 +53,30 @@ impl LogDiagnosticsPlugin { } fn log_diagnostic(diagnostic: &Diagnostic) { - if let Some(value) = diagnostic.smoothed() { - if diagnostic.get_max_history_length() > 1 { - if let Some(average) = diagnostic.average() { - info!( - target: "bevy diagnostic", - // Suffix is only used for 's' or 'ms' currently, - // so we reserve two columns for it; however, - // Do not reserve columns for the suffix in the average - // The ) hugging the value is more aesthetically pleasing - "{name:11.6}{suffix:2} (avg {average:>.6}{suffix:})", - name = diagnostic.name, - suffix = diagnostic.suffix, - name_width = crate::MAX_DIAGNOSTIC_NAME_WIDTH, - ); - return; - } + let Some(value) = diagnostic.smoothed() else { return }; + if diagnostic.get_max_history_length() > 1 { + if let Some(average) = diagnostic.average() { + info!( + target: "bevy diagnostic", + // Suffix is only used for 's' or 'ms' currently, + // so we reserve two columns for it; however, + // Do not reserve columns for the suffix in the average + // The ) hugging the value is more aesthetically pleasing + "{name:11.6}{suffix:2} (avg {average:>.6}{suffix:})", + name = diagnostic.name, + suffix = diagnostic.suffix, + name_width = crate::MAX_DIAGNOSTIC_NAME_WIDTH, + ); + return; } - info!( - target: "bevy diagnostic", - "{name:.6}{suffix:}", - name = diagnostic.name, - suffix = diagnostic.suffix, - name_width = crate::MAX_DIAGNOSTIC_NAME_WIDTH, - ); } + info!( + target: "bevy diagnostic", + "{name:.6}{suffix:}", + name = diagnostic.name, + suffix = diagnostic.suffix, + name_width = crate::MAX_DIAGNOSTIC_NAME_WIDTH, + ); } fn log_diagnostics_system( diff --git a/crates/bevy_ecs/src/schedule/run_criteria.rs b/crates/bevy_ecs/src/schedule/run_criteria.rs index 8bfd84bf04c22..7e9835b0be244 100644 --- a/crates/bevy_ecs/src/schedule/run_criteria.rs +++ b/crates/bevy_ecs/src/schedule/run_criteria.rs @@ -81,17 +81,14 @@ impl BoxedRunCriteria { } pub(crate) fn should_run(&mut self, world: &mut World) -> ShouldRun { - if let Some(ref mut run_criteria) = self.criteria_system { - if !self.initialized { - run_criteria.initialize(world); - self.initialized = true; - } - let should_run = run_criteria.run((), world); - run_criteria.apply_buffers(world); - should_run - } else { - ShouldRun::Yes + let Some(ref mut run_criteria) = self.criteria_system else { return ShouldRun::Yes }; + if !self.initialized { + run_criteria.initialize(world); + self.initialized = true; } + let should_run = run_criteria.run((), world); + run_criteria.apply_buffers(world); + should_run } } @@ -153,11 +150,10 @@ impl GraphNode for RunCriteriaContainer { } fn labels(&self) -> &[RunCriteriaLabelId] { - if let Some(ref label) = self.label { - std::slice::from_ref(label) - } else { - &[] - } + self.label + .as_ref() + .map(|label| std::slice::from_ref(label)) + .unwrap_or(&[]) } fn before(&self) -> &[RunCriteriaLabelId] { diff --git a/crates/bevy_ecs/src/storage/blob_vec.rs b/crates/bevy_ecs/src/storage/blob_vec.rs index c0bfa3302572c..46bd2b03dd7be 100644 --- a/crates/bevy_ecs/src/storage/blob_vec.rs +++ b/crates/bevy_ecs/src/storage/blob_vec.rs @@ -303,16 +303,15 @@ impl BlobVec { // We set len to 0 _before_ dropping elements for unwind safety. This ensures we don't // accidentally drop elements twice in the event of a drop impl panicking. self.len = 0; - if let Some(drop) = self.drop { - let layout_size = self.item_layout.size(); - for i in 0..len { - // SAFETY: `i * layout_size` is inbounds for the allocation, and the item is left unreachable so it can be safely promoted to an `OwningPtr` - unsafe { - // NOTE: this doesn't use self.get_unchecked(i) because the debug_assert on index - // will panic here due to self.len being set to 0 - let ptr = self.get_ptr_mut().byte_add(i * layout_size).promote(); - (drop)(ptr); - } + let Some(drop) = self.drop else { return }; + let layout_size = self.item_layout.size(); + for i in 0..len { + // SAFETY: `i * layout_size` is inbounds for the allocation, and the item is left unreachable so it can be safely promoted to an `OwningPtr` + unsafe { + // NOTE: this doesn't use self.get_unchecked(i) because the debug_assert on index + // will panic here due to self.len being set to 0 + let ptr = self.get_ptr_mut().byte_add(i * layout_size).promote(); + (drop)(ptr); } } } diff --git a/crates/bevy_ecs/src/storage/sparse_set.rs b/crates/bevy_ecs/src/storage/sparse_set.rs index cc3da14682cb9..bba4cce31cfb3 100644 --- a/crates/bevy_ecs/src/storage/sparse_set.rs +++ b/crates/bevy_ecs/src/storage/sparse_set.rs @@ -271,26 +271,23 @@ impl ComponentSparseSet { } pub(crate) fn remove(&mut self, entity: Entity) -> bool { - if let Some(dense_index) = self.sparse.remove(entity.index()) { - let dense_index = dense_index as usize; + let Some(dense_index) = self.sparse.remove(entity.index()) else { return false }; + let dense_index = dense_index as usize; + #[cfg(debug_assertions)] + assert_eq!(entity, self.entities[dense_index]); + self.entities.swap_remove(dense_index); + let is_last = dense_index == self.dense.len() - 1; + // SAFETY: if the sparse index points to something in the dense vec, it exists + unsafe { self.dense.swap_remove_unchecked(TableRow::new(dense_index)) } + if !is_last { + let swapped_entity = self.entities[dense_index]; + #[cfg(not(debug_assertions))] + let index = swapped_entity; #[cfg(debug_assertions)] - assert_eq!(entity, self.entities[dense_index]); - self.entities.swap_remove(dense_index); - let is_last = dense_index == self.dense.len() - 1; - // SAFETY: if the sparse index points to something in the dense vec, it exists - unsafe { self.dense.swap_remove_unchecked(TableRow::new(dense_index)) } - if !is_last { - let swapped_entity = self.entities[dense_index]; - #[cfg(not(debug_assertions))] - let index = swapped_entity; - #[cfg(debug_assertions)] - let index = swapped_entity.index(); - *self.sparse.get_mut(index).unwrap() = dense_index as u32; - } - true - } else { - false + let index = swapped_entity.index(); + *self.sparse.get_mut(index).unwrap() = dense_index as u32; } + true } pub(crate) fn check_change_ticks(&mut self, change_tick: u32) { diff --git a/crates/bevy_ecs/src/system/commands/mod.rs b/crates/bevy_ecs/src/system/commands/mod.rs index 9f1c46a2e7b2b..cead840a012de 100644 --- a/crates/bevy_ecs/src/system/commands/mod.rs +++ b/crates/bevy_ecs/src/system/commands/mod.rs @@ -914,11 +914,11 @@ where T: Bundle + 'static, { fn write(self, world: &mut World) { - if let Some(mut entity) = world.get_entity_mut(self.entity) { - entity.insert(self.bundle); - } else { - panic!("error[B0003]: Could not insert a bundle (of type `{}`) for entity {:?} because it doesn't exist in this World.", std::any::type_name::(), self.entity); - } + world.get_entity_mut(self.entity) + .unwrap_or_else(|| { + panic!("error[B0003]: Could not insert a bundle (of type `{}`) for entity {:?} because it doesn't exist in this World.", std::any::type_name::(), self.entity); + }) + .insert(self.bundle); } } @@ -933,11 +933,10 @@ where T: Bundle, { fn write(self, world: &mut World) { - if let Some(mut entity_mut) = world.get_entity_mut(self.entity) { - // remove intersection to gracefully handle components that were removed before running - // this command - entity_mut.remove_intersection::(); - } + let Some(mut entity_mut) = world.get_entity_mut(self.entity) else { return }; + // remove intersection to gracefully handle components that were removed before running + // this command + entity_mut.remove_intersection::(); } } diff --git a/crates/bevy_ecs/src/world/entity_ref.rs b/crates/bevy_ecs/src/world/entity_ref.rs index 251945d711b09..f3fb631664c5c 100644 --- a/crates/bevy_ecs/src/world/entity_ref.rs +++ b/crates/bevy_ecs/src/world/entity_ref.rs @@ -609,11 +609,10 @@ impl<'w> EntityMut<'w> { }; }; - if let Some(moved_entity) = moved_entity { - let moved_location = world.entities.get(moved_entity).unwrap(); - world.archetypes[moved_location.archetype_id] - .set_entity_table_row(moved_location.archetype_row, table_row); - } + let Some(moved_entity) = moved_entity else { return }; + let moved_location = world.entities.get(moved_entity).unwrap(); + world.archetypes[moved_location.archetype_id] + .set_entity_table_row(moved_location.archetype_row, table_row); } #[inline] @@ -905,11 +904,11 @@ unsafe fn get_ticks_with_type( } fn contains_component_with_type(world: &World, type_id: TypeId, location: EntityLocation) -> bool { - if let Some(component_id) = world.components.get_id(type_id) { - contains_component_with_id(world, component_id, location) - } else { - false - } + world + .components + .get_id(type_id) + .map(|component_id| contains_component_with_id(world, component_id, location)) + .unwrap_or(false) } fn contains_component_with_id( @@ -950,7 +949,6 @@ unsafe fn remove_bundle_from_archetype( } }; let result = if let Some(result) = remove_bundle_result { - // this Bundle removal result is cached. just return that! result } else { let mut next_table_components; diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index e4569f6be5220..6f250abed6d7d 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -739,11 +739,10 @@ impl World { /// Returns an iterator of entities that had components of type `T` removed /// since the last call to [`World::clear_trackers`]. pub fn removed(&self) -> std::iter::Cloned> { - if let Some(component_id) = self.components.get_id(TypeId::of::()) { - self.removed_with_id(component_id) - } else { - [].iter().cloned() - } + self.components + .get_id(TypeId::of::()) + .map(|component_id| self.removed_with_id(component_id)) + .unwrap_or([].iter().cloned()) } /// Returns an iterator of entities that had components with the given `component_id` removed @@ -752,11 +751,10 @@ impl World { &self, component_id: ComponentId, ) -> std::iter::Cloned> { - if let Some(removed) = self.removed_components.get(component_id) { - removed.iter().cloned() - } else { - [].iter().cloned() - } + self.removed_components + .get(component_id) + .map(|removed| removed.iter().cloned()) + .unwrap_or([].iter().cloned()) } /// Inserts a new resource with standard starting values. diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index 81d793993ac7c..448f5c681da68 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -919,11 +919,10 @@ fn primitive_label(mesh: &gltf::Mesh, primitive: &Primitive) -> String { /// Returns the label for the `material`. fn material_label(material: &gltf::Material) -> String { - if let Some(index) = material.index() { - format!("Material{index}") - } else { - "MaterialDefault".to_string() - } + material + .index() + .map(|index| format!("Material{index}")) + .unwrap_or_else(|| "MaterialDefault".to_string()) } /// Returns the label for the `texture`. @@ -1049,11 +1048,8 @@ async fn load_buffers( buffer_data.push(buffer_bytes); } gltf::buffer::Source::Bin => { - if let Some(blob) = gltf.blob.as_deref() { - buffer_data.push(blob.into()); - } else { - return Err(GltfError::MissingBlob); - } + let blob = gltf.blob.as_deref().ok_or(GltfError::MissingBlob)?; + buffer_data.push(blob.into()); } } } @@ -1092,17 +1088,15 @@ fn resolve_node_hierarchy( let (label, node, children) = unprocessed_nodes.remove(&index).unwrap(); assert!(children.is_empty()); nodes.insert(index, (label, node)); - if let Some(parent_index) = parents[index] { - let (_, parent_node, parent_children) = - unprocessed_nodes.get_mut(&parent_index).unwrap(); + let Some(parent_index) = parents[index] else { continue }; + let (_, parent_node, parent_children) = unprocessed_nodes.get_mut(&parent_index).unwrap(); - assert!(parent_children.remove(&index)); - if let Some((_, child_node)) = nodes.get(&index) { - parent_node.children.push(child_node.clone()); - } - if parent_children.is_empty() { - empty_children.push_back(parent_index); - } + assert!(parent_children.remove(&index)); + if let Some((_, child_node)) = nodes.get(&index) { + parent_node.children.push(child_node.clone()); + } + if parent_children.is_empty() { + empty_children.push_back(parent_index); } } if !unprocessed_nodes.is_empty() { diff --git a/crates/bevy_hierarchy/src/child_builder.rs b/crates/bevy_hierarchy/src/child_builder.rs index 9e2c328348d04..ce48497d7ed89 100644 --- a/crates/bevy_hierarchy/src/child_builder.rs +++ b/crates/bevy_hierarchy/src/child_builder.rs @@ -42,11 +42,10 @@ fn update_parent(world: &mut World, child: Entity, new_parent: Entity) -> Option /// Removes the [`Children`] component from the parent if it's empty. fn remove_from_children(world: &mut World, parent: Entity, child: Entity) { let mut parent = world.entity_mut(parent); - if let Some(mut children) = parent.get_mut::() { - children.0.retain(|x| *x != child); - if children.is_empty() { - parent.remove::(); - } + let Some(mut children) = parent.get_mut::() else { return }; + children.0.retain(|x| *x != child); + if children.is_empty() { + parent.remove::(); } } @@ -60,24 +59,25 @@ fn remove_from_children(world: &mut World, parent: Entity, child: Entity) { /// Sends [`HierarchyEvent`]'s. fn update_old_parent(world: &mut World, child: Entity, parent: Entity) { let previous = update_parent(world, child, parent); - if let Some(previous_parent) = previous { - // Do nothing if the child was already parented to this entity. - if previous_parent == parent { - return; - } - remove_from_children(world, previous_parent, child); - - push_events( - world, - [HierarchyEvent::ChildMoved { - child, - previous_parent, - new_parent: parent, - }], - ); - } else { + let Some(previous_parent) = previous else { push_events(world, [HierarchyEvent::ChildAdded { child, parent }]); + return; + }; + + // Do nothing if the child was already parented to this entity. + if previous_parent == parent { + return; } + remove_from_children(world, previous_parent, child); + + push_events( + world, + [HierarchyEvent::ChildMoved { + child, + previous_parent, + new_parent: parent, + }], + ); } /// Update the [`Parent`] components of the `children`. @@ -91,36 +91,35 @@ fn update_old_parent(world: &mut World, child: Entity, parent: Entity) { fn update_old_parents(world: &mut World, parent: Entity, children: &[Entity]) { let mut events: SmallVec<[HierarchyEvent; 8]> = SmallVec::with_capacity(children.len()); for &child in children { - if let Some(previous) = update_parent(world, child, parent) { - // Do nothing if the entity already has the correct parent. - if parent == previous { - continue; - } - - remove_from_children(world, previous, child); - events.push(HierarchyEvent::ChildMoved { - child, - previous_parent: previous, - new_parent: parent, - }); - } else { + let Some(previous) = update_parent(world, child, parent) else { events.push(HierarchyEvent::ChildAdded { child, parent }); + continue; + }; + + // Do nothing if the entity already has the correct parent. + if parent == previous { + continue; } + + remove_from_children(world, previous, child); + events.push(HierarchyEvent::ChildMoved { + child, + previous_parent: previous, + new_parent: parent, + }); } push_events(world, events); } fn remove_children(parent: Entity, children: &[Entity], world: &mut World) { let mut events: SmallVec<[HierarchyEvent; 8]> = SmallVec::new(); - if let Some(parent_children) = world.get::(parent) { - for &child in children { - if parent_children.contains(&child) { - events.push(HierarchyEvent::ChildRemoved { child, parent }); - } + let Some(parent_children) = world.get::(parent) else { return }; + for &child in children { + if parent_children.contains(&child) { + events.push(HierarchyEvent::ChildRemoved { child, parent }); } - } else { - return; } + for event in &events { if let &HierarchyEvent::ChildRemoved { child, .. } = event { world.entity_mut(child).remove::(); @@ -129,14 +128,13 @@ fn remove_children(parent: Entity, children: &[Entity], world: &mut World) { push_events(world, events); let mut parent = world.entity_mut(parent); - if let Some(mut parent_children) = parent.get_mut::() { - parent_children - .0 - .retain(|parent_child| !children.contains(parent_child)); + let Some(mut parent_children) = parent.get_mut::() else { return }; + parent_children + .0 + .retain(|parent_child| !children.contains(parent_child)); - if parent_children.is_empty() { - parent.remove::(); - } + if parent_children.is_empty() { + parent.remove::(); } } diff --git a/crates/bevy_hierarchy/src/hierarchy.rs b/crates/bevy_hierarchy/src/hierarchy.rs index df81324387b2b..95fbd29891839 100644 --- a/crates/bevy_hierarchy/src/hierarchy.rs +++ b/crates/bevy_hierarchy/src/hierarchy.rs @@ -47,10 +47,9 @@ fn despawn_with_children_recursive_inner(world: &mut World, entity: Entity) { } fn despawn_children(world: &mut World, entity: Entity) { - if let Some(mut children) = world.get_mut::(entity) { - for e in std::mem::take(&mut children.0) { - despawn_with_children_recursive_inner(world, e); - } + let Some(mut children) = world.get_mut::(entity) else { return }; + for e in std::mem::take(&mut children.0) { + despawn_with_children_recursive_inner(world, e); } } diff --git a/crates/bevy_log/src/android_tracing.rs b/crates/bevy_log/src/android_tracing.rs index a5e7bc8626b2e..2d58d5d72a803 100644 --- a/crates/bevy_log/src/android_tracing.rs +++ b/crates/bevy_log/src/android_tracing.rs @@ -58,19 +58,16 @@ impl LookupSpan<'a>> Layer for AndroidLayer { let mut new_debug_record = StringRecorder::new(); attrs.record(&mut new_debug_record); - if let Some(span_ref) = ctx.span(id) { - span_ref - .extensions_mut() - .insert::(new_debug_record); - } + let Some(span_ref) = ctx.span(id) else { return }; + span_ref + .extensions_mut() + .insert::(new_debug_record); } fn on_record(&self, id: &Id, values: &Record<'_>, ctx: Context<'_, S>) { - if let Some(span_ref) = ctx.span(id) { - if let Some(debug_record) = span_ref.extensions_mut().get_mut::() { - values.record(debug_record); - } - } + let Some(span_ref) = ctx.span(id) else { return }; + let Some(debug_record) = span_ref.extensions_mut().get_mut::() else { return }; + values.record(debug_record); } fn on_event(&self, event: &Event<'_>, _ctx: Context<'_, S>) { diff --git a/crates/bevy_pbr/src/light.rs b/crates/bevy_pbr/src/light.rs index 69188850f535b..1c8a64634aa2e 100644 --- a/crates/bevy_pbr/src/light.rs +++ b/crates/bevy_pbr/src/light.rs @@ -1327,65 +1327,63 @@ pub(crate) fn assign_lights_to_clusters( * clusters.dimensions.z + z) as usize; - if let Some((view_light_direction, angle_sin, angle_cos)) = + let Some((view_light_direction, angle_sin, angle_cos)) = spot_light_dir_sin_cos - { - for x in min_x..=max_x { - // further culling for spot lights - // get or initialize cluster bounding sphere - let cluster_aabb_sphere = &mut cluster_aabb_spheres[cluster_index]; - let cluster_aabb_sphere = if let Some(sphere) = cluster_aabb_sphere - { - &*sphere - } else { - let aabb = compute_aabb_for_cluster( - first_slice_depth, - far_z, - clusters.tile_size.as_vec2(), - screen_size.as_vec2(), - inverse_projection, - is_orthographic, - clusters.dimensions, - UVec3::new(x, y, z), - ); - let sphere = Sphere { - center: aabb.center, - radius: aabb.half_extents.length(), - }; - *cluster_aabb_sphere = Some(sphere); - cluster_aabb_sphere.as_ref().unwrap() - }; + else { + for _ in min_x..=max_x { + // all clusters within range are affected by point lights + clusters.lights[cluster_index].entities.push(light.entity); + clusters.lights[cluster_index].point_light_count += 1; + cluster_index += clusters.dimensions.z as usize; + } + continue; + }; - // test -- based on https://bartwronski.com/2017/04/13/cull-that-cone/ - let spot_light_offset = Vec3::from( - view_light_sphere.center - cluster_aabb_sphere.center, + for x in min_x..=max_x { + // further culling for spot lights + // get or initialize cluster bounding sphere + let cluster_aabb_sphere = &mut cluster_aabb_spheres[cluster_index]; + let cluster_aabb_sphere = if let Some(sphere) = cluster_aabb_sphere { + &*sphere + } else { + let aabb = compute_aabb_for_cluster( + first_slice_depth, + far_z, + clusters.tile_size.as_vec2(), + screen_size.as_vec2(), + inverse_projection, + is_orthographic, + clusters.dimensions, + UVec3::new(x, y, z), ); - let spot_light_dist_sq = spot_light_offset.length_squared(); - let v1_len = spot_light_offset.dot(view_light_direction); + let sphere = Sphere { + center: aabb.center, + radius: aabb.half_extents.length(), + }; + *cluster_aabb_sphere = Some(sphere); + cluster_aabb_sphere.as_ref().unwrap() + }; - let distance_closest_point = (angle_cos - * (spot_light_dist_sq - v1_len * v1_len).sqrt()) - - v1_len * angle_sin; - let angle_cull = - distance_closest_point > cluster_aabb_sphere.radius; + // test -- based on https://bartwronski.com/2017/04/13/cull-that-cone/ + let spot_light_offset = + Vec3::from(view_light_sphere.center - cluster_aabb_sphere.center); + let spot_light_dist_sq = spot_light_offset.length_squared(); + let v1_len = spot_light_offset.dot(view_light_direction); - let front_cull = v1_len > cluster_aabb_sphere.radius + light.range; - let back_cull = v1_len < -cluster_aabb_sphere.radius; + let distance_closest_point = (angle_cos + * (spot_light_dist_sq - v1_len * v1_len).sqrt()) + - v1_len * angle_sin; + let angle_cull = distance_closest_point > cluster_aabb_sphere.radius; - if !angle_cull && !front_cull && !back_cull { - // this cluster is affected by the spot light - clusters.lights[cluster_index].entities.push(light.entity); - clusters.lights[cluster_index].spot_light_count += 1; - } - cluster_index += clusters.dimensions.z as usize; - } - } else { - for _ in min_x..=max_x { - // all clusters within range are affected by point lights + let front_cull = v1_len > cluster_aabb_sphere.radius + light.range; + let back_cull = v1_len < -cluster_aabb_sphere.radius; + + if !angle_cull && !front_cull && !back_cull { + // this cluster is affected by the spot light clusters.lights[cluster_index].entities.push(light.entity); - clusters.lights[cluster_index].point_light_count += 1; - cluster_index += clusters.dimensions.z as usize; + clusters.lights[cluster_index].spot_light_count += 1; } + cluster_index += clusters.dimensions.z as usize; } } } diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index d10fac03a684e..9fb5610ede18e 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -365,65 +365,60 @@ pub fn queue_material_meshes( let rangefinder = view.rangefinder3d(); for visible_entity in &visible_entities.entities { - if let Ok((material_handle, mesh_handle, mesh_uniform)) = - material_meshes.get(*visible_entity) - { - if let Some(material) = render_materials.get(material_handle) { - if let Some(mesh) = render_meshes.get(mesh_handle) { - let mut mesh_key = - MeshPipelineKey::from_primitive_topology(mesh.primitive_topology) - | view_key; - let alpha_mode = material.properties.alpha_mode; - if let AlphaMode::Blend = alpha_mode { - mesh_key |= MeshPipelineKey::TRANSPARENT_MAIN_PASS; - } - - let pipeline_id = pipelines.specialize( - &mut pipeline_cache, - &material_pipeline, - MaterialPipelineKey { - mesh_key, - bind_group_data: material.key.clone(), - }, - &mesh.layout, - ); - let pipeline_id = match pipeline_id { - Ok(id) => id, - Err(err) => { - error!("{}", err); - continue; - } - }; - - let distance = rangefinder.distance(&mesh_uniform.transform) - + material.properties.depth_bias; - match alpha_mode { - AlphaMode::Opaque => { - opaque_phase.add(Opaque3d { - entity: *visible_entity, - draw_function: draw_opaque_pbr, - pipeline: pipeline_id, - distance, - }); - } - AlphaMode::Mask(_) => { - alpha_mask_phase.add(AlphaMask3d { - entity: *visible_entity, - draw_function: draw_alpha_mask_pbr, - pipeline: pipeline_id, - distance, - }); - } - AlphaMode::Blend => { - transparent_phase.add(Transparent3d { - entity: *visible_entity, - draw_function: draw_transparent_pbr, - pipeline: pipeline_id, - distance, - }); - } - } - } + let Ok((material_handle, mesh_handle, mesh_uniform)) = + material_meshes.get(*visible_entity) else { continue }; + let Some(material) = render_materials.get(material_handle) else { continue }; + let Some(mesh) = render_meshes.get(mesh_handle) else { continue }; + let mut mesh_key = + MeshPipelineKey::from_primitive_topology(mesh.primitive_topology) | view_key; + let alpha_mode = material.properties.alpha_mode; + if let AlphaMode::Blend = alpha_mode { + mesh_key |= MeshPipelineKey::TRANSPARENT_MAIN_PASS; + } + + let pipeline_id = pipelines.specialize( + &mut pipeline_cache, + &material_pipeline, + MaterialPipelineKey { + mesh_key, + bind_group_data: material.key.clone(), + }, + &mesh.layout, + ); + let pipeline_id = match pipeline_id { + Ok(id) => id, + Err(err) => { + error!("{}", err); + continue; + } + }; + + let distance = + rangefinder.distance(&mesh_uniform.transform) + material.properties.depth_bias; + match alpha_mode { + AlphaMode::Opaque => { + opaque_phase.add(Opaque3d { + entity: *visible_entity, + draw_function: draw_opaque_pbr, + pipeline: pipeline_id, + distance, + }); + } + AlphaMode::Mask(_) => { + alpha_mask_phase.add(AlphaMask3d { + entity: *visible_entity, + draw_function: draw_alpha_mask_pbr, + pipeline: pipeline_id, + distance, + }); + } + AlphaMode::Blend => { + transparent_phase.add(Transparent3d { + entity: *visible_entity, + draw_function: draw_transparent_pbr, + pipeline: pipeline_id, + distance, + }); } } } diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index 9cd2bf0bbd83c..2be1497457918 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -1574,18 +1574,16 @@ pub fn prepare_clusters( if !indices_full { for entity in cluster_lights.iter() { - if let Some(light_index) = global_light_meta.entity_to_index.get(entity) + let Some(light_index) = global_light_meta.entity_to_index.get(entity) else { continue }; + if view_clusters_bindings.n_indices() + >= ViewClusterBindings::MAX_INDICES + && !supports_storage_buffers { - if view_clusters_bindings.n_indices() - >= ViewClusterBindings::MAX_INDICES - && !supports_storage_buffers - { - warn!("Cluster light index lists is full! The PointLights in the view are affecting too many clusters."); - indices_full = true; - break; - } - view_clusters_bindings.push_index(*light_index); + warn!("Cluster light index lists is full! The PointLights in the view are affecting too many clusters."); + indices_full = true; + break; } + view_clusters_bindings.push_index(*light_index); } } @@ -1606,17 +1604,16 @@ pub fn queue_shadow_view_bind_group( mut light_meta: ResMut, view_uniforms: Res, ) { - if let Some(view_binding) = view_uniforms.uniforms.binding() { - light_meta.shadow_view_bind_group = - Some(render_device.create_bind_group(&BindGroupDescriptor { - entries: &[BindGroupEntry { - binding: 0, - resource: view_binding, - }], - label: Some("shadow_view_bind_group"), - layout: &shadow_pipeline.view_layout, - })); - } + let Some(view_binding) = view_uniforms.uniforms.binding() else { return }; + light_meta.shadow_view_bind_group = + Some(render_device.create_bind_group(&BindGroupDescriptor { + entries: &[BindGroupEntry { + binding: 0, + resource: view_binding, + }], + label: Some("shadow_view_bind_group"), + layout: &shadow_pipeline.view_layout, + })); } #[allow(clippy::too_many_arguments)] @@ -1656,33 +1653,26 @@ pub fn queue_shadows( // NOTE: Lights with shadow mapping disabled will have no visible entities // so no meshes will be queued for entity in visible_entities.iter().copied() { - if let Ok(mesh_handle) = casting_meshes.get(entity) { - if let Some(mesh) = render_meshes.get(mesh_handle) { - let key = - ShadowPipelineKey::from_primitive_topology(mesh.primitive_topology); - let pipeline_id = pipelines.specialize( - &mut pipeline_cache, - &shadow_pipeline, - key, - &mesh.layout, - ); - - let pipeline_id = match pipeline_id { - Ok(id) => id, - Err(err) => { - error!("{}", err); - continue; - } - }; - - shadow_phase.add(Shadow { - draw_function: draw_shadow_mesh, - pipeline: pipeline_id, - entity, - distance: 0.0, // TODO: sort back-to-front - }); + let Ok(mesh_handle) = casting_meshes.get(entity) else { continue }; + let Some(mesh) = render_meshes.get(mesh_handle) else { continue }; + let key = ShadowPipelineKey::from_primitive_topology(mesh.primitive_topology); + let pipeline_id = + pipelines.specialize(&mut pipeline_cache, &shadow_pipeline, key, &mesh.layout); + + let pipeline_id = match pipeline_id { + Ok(id) => id, + Err(err) => { + error!("{}", err); + continue; } - } + }; + + shadow_phase.add(Shadow { + draw_function: draw_shadow_mesh, + pipeline: pipeline_id, + entity, + distance: 0.0, // TODO: sort back-to-front + }); } } } diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index 92b65621922ac..59c742fbf3bf0 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -234,12 +234,11 @@ pub fn extract_skinned_meshes( continue; } // PERF: This can be expensive, can we move this to prepare? - if let Some(skinned_joints) = + let Some(skinned_joints) = SkinnedMeshJoints::build(skin, &inverse_bindposes, &joint_query, &mut uniform.buffer) - { - last_start = last_start.max(skinned_joints.index as usize); - values.push((entity, skinned_joints.to_buffer_index())); - } + else { continue }; + last_start = last_start.max(skinned_joints.index as usize); + values.push((entity, skinned_joints.to_buffer_index())); } // Pad out the buffer to ensure that there's enough space for bindings @@ -717,41 +716,40 @@ pub fn queue_mesh_bind_group( mesh_uniforms: Res>, skinned_mesh_uniform: Res, ) { - if let Some(mesh_binding) = mesh_uniforms.uniforms().binding() { - let mut mesh_bind_group = MeshBindGroup { - normal: render_device.create_bind_group(&BindGroupDescriptor { - entries: &[BindGroupEntry { + let Some(mesh_binding) = mesh_uniforms.uniforms().binding() else { return }; + let mut mesh_bind_group = MeshBindGroup { + normal: render_device.create_bind_group(&BindGroupDescriptor { + entries: &[BindGroupEntry { + binding: 0, + resource: mesh_binding.clone(), + }], + label: Some("mesh_bind_group"), + layout: &mesh_pipeline.mesh_layout, + }), + skinned: None, + }; + + if let Some(skinned_joints_buffer) = skinned_mesh_uniform.buffer.buffer() { + mesh_bind_group.skinned = Some(render_device.create_bind_group(&BindGroupDescriptor { + entries: &[ + BindGroupEntry { binding: 0, - resource: mesh_binding.clone(), - }], - label: Some("mesh_bind_group"), - layout: &mesh_pipeline.mesh_layout, - }), - skinned: None, - }; - - if let Some(skinned_joints_buffer) = skinned_mesh_uniform.buffer.buffer() { - mesh_bind_group.skinned = Some(render_device.create_bind_group(&BindGroupDescriptor { - entries: &[ - BindGroupEntry { - binding: 0, - resource: mesh_binding, - }, - BindGroupEntry { - binding: 1, - resource: BindingResource::Buffer(BufferBinding { - buffer: skinned_joints_buffer, - offset: 0, - size: Some(NonZeroU64::new(JOINT_BUFFER_SIZE as u64).unwrap()), - }), - }, - ], - label: Some("skinned_mesh_bind_group"), - layout: &mesh_pipeline.skinned_mesh_layout, - })); - } - commands.insert_resource(mesh_bind_group); + resource: mesh_binding, + }, + BindGroupEntry { + binding: 1, + resource: BindingResource::Buffer(BufferBinding { + buffer: skinned_joints_buffer, + offset: 0, + size: Some(NonZeroU64::new(JOINT_BUFFER_SIZE as u64).unwrap()), + }), + }, + ], + label: Some("skinned_mesh_bind_group"), + layout: &mesh_pipeline.skinned_mesh_layout, + })); } + commands.insert_resource(mesh_bind_group); } // NOTE: This is using BufferVec because it is using a trick to allow a fixed-size array @@ -947,25 +945,22 @@ impl RenderCommand

for DrawMesh { meshes: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - if let Some(gpu_mesh) = meshes.into_inner().get(mesh_handle) { - pass.set_vertex_buffer(0, gpu_mesh.vertex_buffer.slice(..)); - match &gpu_mesh.buffer_info { - GpuBufferInfo::Indexed { - buffer, - index_format, - count, - } => { - pass.set_index_buffer(buffer.slice(..), 0, *index_format); - pass.draw_indexed(0..*count, 0, 0..1); - } - GpuBufferInfo::NonIndexed { vertex_count } => { - pass.draw(0..*vertex_count, 0..1); - } + let Some(gpu_mesh) = meshes.into_inner().get(mesh_handle) else { return RenderCommandResult::Failure }; + pass.set_vertex_buffer(0, gpu_mesh.vertex_buffer.slice(..)); + match &gpu_mesh.buffer_info { + GpuBufferInfo::Indexed { + buffer, + index_format, + count, + } => { + pass.set_index_buffer(buffer.slice(..), 0, *index_format); + pass.draw_indexed(0..*count, 0, 0..1); + } + GpuBufferInfo::NonIndexed { vertex_count } => { + pass.draw(0..*vertex_count, 0..1); } - RenderCommandResult::Success - } else { - RenderCommandResult::Failure } + RenderCommandResult::Success } } diff --git a/crates/bevy_pbr/src/wireframe.rs b/crates/bevy_pbr/src/wireframe.rs index 2b31a051317d2..c5d34de05b742 100644 --- a/crates/bevy_pbr/src/wireframe.rs +++ b/crates/bevy_pbr/src/wireframe.rs @@ -124,29 +124,28 @@ fn queue_wireframes( let view_key = msaa_key | MeshPipelineKey::from_hdr(view.hdr); let add_render_phase = |(entity, mesh_handle, mesh_uniform): (Entity, &Handle, &MeshUniform)| { - if let Some(mesh) = render_meshes.get(mesh_handle) { - let key = view_key - | MeshPipelineKey::from_primitive_topology(mesh.primitive_topology); - let pipeline_id = pipelines.specialize( - &mut pipeline_cache, - &wireframe_pipeline, - key, - &mesh.layout, - ); - let pipeline_id = match pipeline_id { - Ok(id) => id, - Err(err) => { - error!("{}", err); - return; - } - }; - opaque_phase.add(Opaque3d { - entity, - pipeline: pipeline_id, - draw_function: draw_custom, - distance: rangefinder.distance(&mesh_uniform.transform), - }); - } + let Some(mesh) = render_meshes.get(mesh_handle) else { return }; + let key = + view_key | MeshPipelineKey::from_primitive_topology(mesh.primitive_topology); + let pipeline_id = pipelines.specialize( + &mut pipeline_cache, + &wireframe_pipeline, + key, + &mesh.layout, + ); + let pipeline_id = match pipeline_id { + Ok(id) => id, + Err(err) => { + error!("{}", err); + return; + } + }; + opaque_phase.add(Opaque3d { + entity, + pipeline: pipeline_id, + draw_function: draw_custom, + distance: rangefinder.distance(&mesh_uniform.transform), + }); }; if wireframe_config.global { diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/documentation.rs b/crates/bevy_reflect/bevy_reflect_derive/src/documentation.rs index 4bf2474873655..3c53653980715 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/documentation.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/documentation.rs @@ -69,10 +69,9 @@ impl Documentation { impl ToTokens for Documentation { fn to_tokens(&self, tokens: &mut TokenStream) { - if let Some(doc) = self.doc_string() { - quote!(#FQOption::Some(#doc)).to_tokens(tokens); - } else { - quote!(#FQOption::None).to_tokens(tokens); + match self.doc_string() { + Some(doc) => quote!(#FQOption::Some(#doc)).to_tokens(tokens), + None => quote!(#FQOption::None).to_tokens(tokens), } } } diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs b/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs index 0e19b8429e581..2b3c7d37004e3 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs @@ -79,12 +79,11 @@ pub(crate) fn parse_field_attrs(attrs: &[Attribute]) -> Result { } fn apply(&mut self, value: &dyn Reflect) { - let value = value.as_any(); - if let Some(value) = value.downcast_ref::() { - *self = value.clone(); - } else { - panic!("Value is not a {}.", std::any::type_name::()); - } + *self = value + .as_any() + .downcast_ref::() + .unwrap_or_else(|| panic!("Value is not a {}.", std::any::type_name::())) + .clone(); } fn set(&mut self, value: Box) -> Result<(), Box> { @@ -998,12 +997,11 @@ impl Reflect for Cow<'static, str> { } fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option { - let value = value.as_any(); - if let Some(value) = value.downcast_ref::() { - Some(std::cmp::PartialEq::eq(self, value)) - } else { - Some(false) - } + value + .as_any() + .downcast_ref::() + .map(|value| std::cmp::PartialEq::eq(self, value)) + .or(Some(false)) } } @@ -1069,12 +1067,10 @@ impl Reflect for &'static Path { } fn apply(&mut self, value: &dyn Reflect) { - let value = value.as_any(); - if let Some(&value) = value.downcast_ref::() { - *self = value; - } else { - panic!("Value is not a {}.", std::any::type_name::()); - } + *self = value + .as_any() + .downcast_ref::() + .unwrap_or_else(|| panic!("Value is not a {}.", std::any::type_name::())); } fn set(&mut self, value: Box) -> Result<(), Box> { @@ -1106,12 +1102,11 @@ impl Reflect for &'static Path { } fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option { - let value = value.as_any(); - if let Some(value) = value.downcast_ref::() { - Some(std::cmp::PartialEq::eq(self, value)) - } else { - Some(false) - } + value + .as_any() + .downcast_ref::() + .map(|value| std::cmp::PartialEq::eq(self, value)) + .or(Some(false)) } } diff --git a/crates/bevy_reflect/src/path.rs b/crates/bevy_reflect/src/path.rs index 0b508fa0f749e..17e5196e863f3 100644 --- a/crates/bevy_reflect/src/path.rs +++ b/crates/bevy_reflect/src/path.rs @@ -110,42 +110,40 @@ impl GetPath for dyn Reflect { let current_index = index; match token { Token::Dot => { - if let Some(Token::Ident(value)) = next_token(path, &mut index) { - current = read_field(current, value, current_index)?; - } else { + let Some(Token::Ident(value)) = next_token(path, &mut index) else { return Err(ReflectPathError::ExpectedIdent { index: current_index, }); - } + }; + current = read_field(current, value, current_index)?; } Token::OpenBracket => { - if let Some(Token::Ident(value)) = next_token(path, &mut index) { - match current.reflect_ref() { - ReflectRef::List(reflect_list) => { - current = read_array_entry(reflect_list, value, current_index)?; - } - ReflectRef::Array(reflect_arr) => { - current = read_array_entry(reflect_arr, value, current_index)?; - } - _ => { - return Err(ReflectPathError::ExpectedList { - index: current_index, - }) - } - } - } else { + let Some(Token::Ident(value)) = next_token(path, &mut index) else { return Err(ReflectPathError::ExpectedIdent { index: current_index, }); + }; + + match current.reflect_ref() { + ReflectRef::List(reflect_list) => { + current = read_array_entry(reflect_list, value, current_index)?; + } + ReflectRef::Array(reflect_arr) => { + current = read_array_entry(reflect_arr, value, current_index)?; + } + _ => { + return Err(ReflectPathError::ExpectedList { + index: current_index, + }) + } } - if let Some(Token::CloseBracket) = next_token(path, &mut index) { - } else { + let Some(Token::CloseBracket) = next_token(path, &mut index) else { return Err(ReflectPathError::ExpectedToken { index: current_index, token: "]", }); - } + }; } Token::CloseBracket => { return Err(ReflectPathError::UnexpectedToken { @@ -172,42 +170,40 @@ impl GetPath for dyn Reflect { let current_index = index; match token { Token::Dot => { - if let Some(Token::Ident(value)) = next_token(path, &mut index) { - current = read_field_mut(current, value, current_index)?; - } else { + let Some(Token::Ident(value)) = next_token(path, &mut index) else { return Err(ReflectPathError::ExpectedIdent { index: current_index, }); - } + }; + current = read_field_mut(current, value, current_index)?; } Token::OpenBracket => { - if let Some(Token::Ident(value)) = next_token(path, &mut index) { - match current.reflect_mut() { - ReflectMut::List(reflect_list) => { - current = read_array_entry_mut(reflect_list, value, current_index)?; - } - ReflectMut::Array(reflect_arr) => { - current = read_array_entry_mut(reflect_arr, value, current_index)?; - } - _ => { - return Err(ReflectPathError::ExpectedStruct { - index: current_index, - }) - } - } - } else { + let Some(Token::Ident(value)) = next_token(path, &mut index) else { return Err(ReflectPathError::ExpectedIdent { index: current_index, }); + }; + + match current.reflect_mut() { + ReflectMut::List(reflect_list) => { + current = read_array_entry_mut(reflect_list, value, current_index)?; + } + ReflectMut::Array(reflect_arr) => { + current = read_array_entry_mut(reflect_arr, value, current_index)?; + } + _ => { + return Err(ReflectPathError::ExpectedStruct { + index: current_index, + }) + } } - if let Some(Token::CloseBracket) = next_token(path, &mut index) { - } else { + let Some(Token::CloseBracket) = next_token(path, &mut index) else { return Err(ReflectPathError::ExpectedToken { index: current_index, token: "]", }); - } + }; } Token::CloseBracket => { return Err(ReflectPathError::UnexpectedToken { diff --git a/crates/bevy_reflect/src/serde/de.rs b/crates/bevy_reflect/src/serde/de.rs index 91021d33d68b8..a4242beda0f23 100644 --- a/crates/bevy_reflect/src/serde/de.rs +++ b/crates/bevy_reflect/src/serde/de.rs @@ -339,8 +339,7 @@ impl<'a, 'de> DeserializeSeed<'de> for TypedReflectDeserializer<'a> { // Handle both Value case and types that have a custom `ReflectDeserialize` if let Some(deserialize_reflect) = self.registration.data::() { - let value = deserialize_reflect.deserialize(deserializer)?; - return Ok(value); + return Ok(deserialize_reflect.deserialize(deserializer)?); } match self.registration.type_info() { diff --git a/crates/bevy_reflect/src/struct_trait.rs b/crates/bevy_reflect/src/struct_trait.rs index 4b8485cbb5b3e..d69199bbcde56 100644 --- a/crates/bevy_reflect/src/struct_trait.rs +++ b/crates/bevy_reflect/src/struct_trait.rs @@ -329,11 +329,9 @@ impl Struct for DynamicStruct { #[inline] fn field_mut(&mut self, name: &str) -> Option<&mut dyn Reflect> { - if let Some(index) = self.field_indices.get(name) { - Some(&mut *self.fields[*index]) - } else { - None - } + self.field_indices + .get(name) + .map(|index| &mut *self.fields[*index]) } #[inline] @@ -443,9 +441,8 @@ impl Reflect for DynamicStruct { if let ReflectRef::Struct(struct_value) = value.reflect_ref() { for (i, value) in struct_value.iter_fields().enumerate() { let name = struct_value.name_at(i).unwrap(); - if let Some(v) = self.field_mut(name) { - v.apply(value); - } + let Some(v) = self.field_mut(name) else { continue }; + v.apply(value); } } else { panic!("Attempted to apply non-struct type to struct type."); diff --git a/crates/bevy_reflect/src/tuple_struct.rs b/crates/bevy_reflect/src/tuple_struct.rs index e8c52bdadddbd..b7e485a66f086 100644 --- a/crates/bevy_reflect/src/tuple_struct.rs +++ b/crates/bevy_reflect/src/tuple_struct.rs @@ -345,9 +345,8 @@ impl Reflect for DynamicTupleStruct { fn apply(&mut self, value: &dyn Reflect) { if let ReflectRef::TupleStruct(tuple_struct) = value.reflect_ref() { for (i, value) in tuple_struct.iter_fields().enumerate() { - if let Some(v) = self.field_mut(i) { - v.apply(value); - } + let Some(v) = self.field_mut(i) else { continue }; + v.apply(value); } } else { panic!("Attempted to apply non-TupleStruct type to TupleStruct type."); diff --git a/crates/bevy_render/src/extract_resource.rs b/crates/bevy_render/src/extract_resource.rs index 3fa92750421c8..9c43b163a8f21 100644 --- a/crates/bevy_render/src/extract_resource.rs +++ b/crates/bevy_render/src/extract_resource.rs @@ -46,11 +46,7 @@ pub fn extract_resource( target_resource: Option>, #[cfg(debug_assertions)] mut has_warned_on_remove: Local, ) { - if let Some(mut target_resource) = target_resource { - if main_resource.is_changed() { - *target_resource = R::extract_resource(&main_resource); - } - } else { + let Some(mut target_resource) = target_resource else { #[cfg(debug_assertions)] if !main_resource.is_added() && !*has_warned_on_remove { *has_warned_on_remove = true; @@ -61,5 +57,9 @@ pub fn extract_resource( ); } commands.insert_resource(R::extract_resource(&main_resource)); + return; + }; + if main_resource.is_changed() { + *target_resource = R::extract_resource(&main_resource); } } diff --git a/crates/bevy_render/src/mesh/mesh/mod.rs b/crates/bevy_render/src/mesh/mesh/mod.rs index d58c5e2cf703d..318f094e3b34c 100644 --- a/crates/bevy_render/src/mesh/mesh/mod.rs +++ b/crates/bevy_render/src/mesh/mesh/mod.rs @@ -464,24 +464,22 @@ impl InnerMeshVertexBufferLayout { ) -> Result { let mut attributes = Vec::with_capacity(attribute_descriptors.len()); for attribute_descriptor in attribute_descriptors { - if let Some(index) = self + let Some(index) = self .attribute_ids .iter() - .position(|id| *id == attribute_descriptor.id) - { - let layout_attribute = &self.layout.attributes[index]; - attributes.push(VertexAttribute { - format: layout_attribute.format, - offset: layout_attribute.offset, - shader_location: attribute_descriptor.shader_location, - }); - } else { + .position(|id| *id == attribute_descriptor.id) else { return Err(MissingVertexAttributeError { id: attribute_descriptor.id, name: attribute_descriptor.name, pipeline_type: None, }); - } + }; + let layout_attribute = &self.layout.attributes[index]; + attributes.push(VertexAttribute { + format: layout_attribute.format, + offset: layout_attribute.offset, + shader_location: attribute_descriptor.shader_location, + }); } Ok(VertexBufferLayout { diff --git a/crates/bevy_render/src/render_graph/context.rs b/crates/bevy_render/src/render_graph/context.rs index 6a4ee01afa0ee..ce97cb91892e9 100644 --- a/crates/bevy_render/src/render_graph/context.rs +++ b/crates/bevy_render/src/render_graph/context.rs @@ -171,22 +171,21 @@ impl<'a> RenderGraphContext<'a> { .ok_or_else(|| RunSubGraphError::MissingSubGraph(name.clone()))?; if let Some(input_node) = sub_graph.get_input_node() { for (i, input_slot) in input_node.input_slots.iter().enumerate() { - if let Some(input_value) = inputs.get(i) { - if input_slot.slot_type != input_value.slot_type() { - return Err(RunSubGraphError::MismatchedInputSlotType { - graph_name: name, - slot_index: i, - actual: input_value.slot_type(), - expected: input_slot.slot_type, - label: input_slot.name.clone().into(), - }); - } - } else { + let Some(input_value) = inputs.get(i) else { return Err(RunSubGraphError::MissingInput { slot_index: i, slot_name: input_slot.name.clone(), graph_name: name, }); + }; + if input_slot.slot_type != input_value.slot_type() { + return Err(RunSubGraphError::MismatchedInputSlotType { + graph_name: name, + slot_index: i, + actual: input_value.slot_type(), + expected: input_slot.slot_type, + label: input_slot.name.clone().into(), + }); } } } else if !inputs.is_empty() { diff --git a/crates/bevy_render/src/render_graph/graph.rs b/crates/bevy_render/src/render_graph/graph.rs index e034f345f4e67..a6f107e4033a1 100644 --- a/crates/bevy_render/src/render_graph/graph.rs +++ b/crates/bevy_render/src/render_graph/graph.rs @@ -126,41 +126,39 @@ impl RenderGraph { name: impl Into>, ) -> Result<(), RenderGraphError> { let name = name.into(); - if let Some(id) = self.node_names.remove(&name) { - if let Some(node_state) = self.nodes.remove(&id) { - // Remove all edges from other nodes to this one. Note that as we're removing this - // node, we don't need to remove its input edges - for input_edge in node_state.edges.input_edges().iter() { - match input_edge { - Edge::SlotEdge { output_node, .. } - | Edge::NodeEdge { - input_node: _, - output_node, - } => { - if let Ok(output_node) = self.get_node_state_mut(*output_node) { - output_node.edges.remove_output_edge(input_edge.clone())?; - } - } + let Some(id) = self.node_names.remove(&name) else { return Ok(()) }; + let Some(node_state) = self.nodes.remove(&id) else { return Ok(()) }; + // Remove all edges from other nodes to this one. Note that as we're removing this + // node, we don't need to remove its input edges + for input_edge in node_state.edges.input_edges().iter() { + match input_edge { + Edge::SlotEdge { output_node, .. } + | Edge::NodeEdge { + input_node: _, + output_node, + } => { + if let Ok(output_node) = self.get_node_state_mut(*output_node) { + output_node.edges.remove_output_edge(input_edge.clone())?; } } - // Remove all edges from this node to other nodes. Note that as we're removing this - // node, we don't need to remove its output edges - for output_edge in node_state.edges.output_edges().iter() { - match output_edge { - Edge::SlotEdge { - output_node: _, - output_index: _, - input_node, - input_index: _, - } - | Edge::NodeEdge { - output_node: _, - input_node, - } => { - if let Ok(input_node) = self.get_node_state_mut(*input_node) { - input_node.edges.remove_input_edge(output_edge.clone())?; - } - } + } + } + // Remove all edges from this node to other nodes. Note that as we're removing this + // node, we don't need to remove its output edges + for output_edge in node_state.edges.output_edges().iter() { + match output_edge { + Edge::SlotEdge { + output_node: _, + output_index: _, + input_node, + input_index: _, + } + | Edge::NodeEdge { + output_node: _, + input_node, + } => { + if let Ok(input_node) = self.get_node_state_mut(*input_node) { + input_node.edges.remove_input_edge(output_edge.clone())?; } } } diff --git a/crates/bevy_render/src/render_phase/draw_state.rs b/crates/bevy_render/src/render_phase/draw_state.rs index 907712e6788a6..9635c557ca344 100644 --- a/crates/bevy_render/src/render_phase/draw_state.rs +++ b/crates/bevy_render/src/render_phase/draw_state.rs @@ -40,11 +40,12 @@ impl DrawState { bind_group: BindGroupId, dynamic_indices: &[u32], ) -> bool { - if let Some(current_bind_group) = self.bind_groups.get(index) { - current_bind_group.0 == Some(bind_group) && dynamic_indices == current_bind_group.1 - } else { - false - } + self.bind_groups + .get(index) + .map(|current_bind_group| { + current_bind_group.0 == Some(bind_group) && dynamic_indices == current_bind_group.1 + }) + .unwrap_or(false) } pub fn set_vertex_buffer(&mut self, index: usize, buffer: BufferId, offset: u64) { @@ -55,11 +56,10 @@ impl DrawState { } pub fn is_vertex_buffer_set(&self, index: usize, buffer: BufferId, offset: u64) -> bool { - if let Some(current) = self.vertex_buffers.get(index) { - *current == Some((buffer, offset)) - } else { - false - } + self.vertex_buffers + .get(index) + .map(|current| *current == Some((buffer, offset))) + .unwrap_or(false) } pub fn set_index_buffer(&mut self, buffer: BufferId, offset: u64, index_format: IndexFormat) { diff --git a/crates/bevy_render/src/render_phase/mod.rs b/crates/bevy_render/src/render_phase/mod.rs index b0b502422b928..ef9348ee5b93c 100644 --- a/crates/bevy_render/src/render_phase/mod.rs +++ b/crates/bevy_render/src/render_phase/mod.rs @@ -58,21 +58,20 @@ impl RenderPhase { self.items.reserve(items.len()); // Start the first batch from the first item - if let Some(mut current_batch) = items.next() { - // Batch following items until we find an incompatible item - for next_item in items { - if matches!( - current_batch.add_to_batch(&next_item), - BatchResult::IncompatibleItems - ) { - // Store the completed batch, and start a new one from the incompatible item - self.items.push(current_batch); - current_batch = next_item; - } + let Some(mut current_batch) = items.next() else { return }; + // Batch following items until we find an incompatible item + for next_item in items { + if matches!( + current_batch.add_to_batch(&next_item), + BatchResult::IncompatibleItems + ) { + // Store the completed batch, and start a new one from the incompatible item + self.items.push(current_batch); + current_batch = next_item; } - // Store the last batch - self.items.push(current_batch); } + // Store the last batch + self.items.push(current_batch); } } diff --git a/crates/bevy_render/src/render_resource/buffer_vec.rs b/crates/bevy_render/src/render_resource/buffer_vec.rs index 4a3c744e071c9..4b3b8efa10b83 100644 --- a/crates/bevy_render/src/render_resource/buffer_vec.rs +++ b/crates/bevy_render/src/render_resource/buffer_vec.rs @@ -124,11 +124,10 @@ impl BufferVec { return; } self.reserve(self.values.len(), device); - if let Some(buffer) = &self.buffer { - let range = 0..self.item_size * self.values.len(); - let bytes: &[u8] = cast_slice(&self.values); - queue.write_buffer(buffer, 0, &bytes[range]); - } + let Some(buffer) = &self.buffer else { return }; + let range = 0..self.item_size * self.values.len(); + let bytes: &[u8] = cast_slice(&self.values); + queue.write_buffer(buffer, 0, &bytes[range]); } pub fn truncate(&mut self, len: usize) { diff --git a/crates/bevy_render/src/render_resource/pipeline_cache.rs b/crates/bevy_render/src/render_resource/pipeline_cache.rs index 0209c2e8c9d97..67e1ea8dc79f7 100644 --- a/crates/bevy_render/src/render_resource/pipeline_cache.rs +++ b/crates/bevy_render/src/render_resource/pipeline_cache.rs @@ -238,11 +238,10 @@ impl ShaderCache { let mut shaders_to_clear = vec![handle.clone_weak()]; let mut pipelines_to_queue = Vec::new(); while let Some(handle) = shaders_to_clear.pop() { - if let Some(data) = self.data.get_mut(&handle) { - data.processed_shaders.clear(); - pipelines_to_queue.extend(data.pipelines.iter().cloned()); - shaders_to_clear.extend(data.dependents.iter().map(|h| h.clone_weak())); - } + let Some(data) = self.data.get_mut(&handle) else { continue }; + data.processed_shaders.clear(); + pipelines_to_queue.extend(data.pipelines.iter().cloned()); + shaders_to_clear.extend(data.dependents.iter().map(|h| h.clone_weak())); } pipelines_to_queue @@ -267,18 +266,18 @@ impl ShaderCache { } for import in shader.imports() { - if let Some(import_handle) = self.import_path_shaders.get(import) { - // resolve import because it is currently available - let data = self.data.entry(handle.clone_weak()).or_default(); - data.resolved_imports - .insert(import.clone(), import_handle.clone_weak()); - // add this shader as a dependent of the import - let data = self.data.entry(import_handle.clone_weak()).or_default(); - data.dependents.insert(handle.clone_weak()); - } else { + let Some(import_handle) = self.import_path_shaders.get(import) else { let waiting = self.waiting_on_import.entry(import.clone()).or_default(); waiting.push(handle.clone_weak()); - } + continue; + }; + // resolve import because it is currently available + let data = self.data.entry(handle.clone_weak()).or_default(); + data.resolved_imports + .insert(import.clone(), import_handle.clone_weak()); + // add this shader as a dependent of the import + let data = self.data.entry(import_handle.clone_weak()).or_default(); + data.dependents.insert(handle.clone_weak()); } self.shaders.insert(handle.clone_weak(), shader); @@ -558,17 +557,14 @@ impl PipelineCache { }) .collect::>(); - let layout = if let Some(layout) = &descriptor.layout { - Some(self.layout_cache.get(&self.device, layout)) - } else { - None - }; - let descriptor = RawRenderPipelineDescriptor { multiview: None, depth_stencil: descriptor.depth_stencil.clone(), label: descriptor.label.as_deref(), - layout, + layout: descriptor + .layout + .as_ref() + .map(|layout| self.layout_cache.get(&self.device, layout)), multisample: descriptor.multisample, primitive: descriptor.primitive, vertex: RawVertexState { @@ -607,15 +603,12 @@ impl PipelineCache { } }; - let layout = if let Some(layout) = &descriptor.layout { - Some(self.layout_cache.get(&self.device, layout)) - } else { - None - }; - let descriptor = RawComputePipelineDescriptor { label: descriptor.label.as_deref(), - layout, + layout: descriptor + .layout + .as_ref() + .map(|layout| self.layout_cache.get(&self.device, layout)), module: &compute_module, entry_point: descriptor.entry_point.as_ref(), }; diff --git a/crates/bevy_render/src/render_resource/resource_macros.rs b/crates/bevy_render/src/render_resource/resource_macros.rs index e27380426a169..b657a77904135 100644 --- a/crates/bevy_render/src/render_resource/resource_macros.rs +++ b/crates/bevy_render/src/render_resource/resource_macros.rs @@ -21,27 +21,23 @@ macro_rules! render_resource_wrapper { } pub fn try_unwrap(mut self) -> Option<$wgpu_type> { - let inner = self.0.take(); - if let Some(inner) = inner { - match std::sync::Arc::try_unwrap(inner) { - Ok(untyped_box) => { - let typed_box = unsafe { - std::mem::transmute::, Box<$wgpu_type>>(untyped_box) - }; - Some(*typed_box) - } - Err(inner) => { - let _ = unsafe { - std::mem::transmute::< - std::sync::Arc>, - std::sync::Arc>, - >(inner) - }; - None - } + let inner = self.0.take()?; + match std::sync::Arc::try_unwrap(inner) { + Ok(untyped_box) => { + let typed_box = unsafe { + std::mem::transmute::, Box<$wgpu_type>>(untyped_box) + }; + Some(*typed_box) + } + Err(inner) => { + let _ = unsafe { + std::mem::transmute::< + std::sync::Arc>, + std::sync::Arc>, + >(inner) + }; + None } - } else { - None } } } @@ -64,8 +60,7 @@ macro_rules! render_resource_wrapper { impl Drop for $wrapper_type { fn drop(&mut self) { - let inner = self.0.take(); - if let Some(inner) = inner { + if let Some(inner) = self.0.take() { let _ = unsafe { std::mem::transmute::< std::sync::Arc>, diff --git a/crates/bevy_render/src/render_resource/shader.rs b/crates/bevy_render/src/render_resource/shader.rs index 08f01f64fa81c..3a3775f945ce0 100644 --- a/crates/bevy_render/src/render_resource/shader.rs +++ b/crates/bevy_render/src/render_resource/shader.rs @@ -536,21 +536,19 @@ impl ShaderProcessor { let mut line_with_defs = line.to_string(); for capture in self.def_regex.captures_iter(line) { let def = capture.get(1).unwrap(); - if let Some(def) = shader_defs_unique.get(def.as_str()) { - line_with_defs = self - .def_regex - .replace(&line_with_defs, def.value_as_string()) - .to_string(); - } + let Some(def) = shader_defs_unique.get(def.as_str()) else { continue }; + line_with_defs = self + .def_regex + .replace(&line_with_defs, def.value_as_string()) + .to_string(); } for capture in self.def_regex_delimited.captures_iter(line) { let def = capture.get(1).unwrap(); - if let Some(def) = shader_defs_unique.get(def.as_str()) { - line_with_defs = self - .def_regex_delimited - .replace(&line_with_defs, def.value_as_string()) - .to_string(); - } + let Some(def) = shader_defs_unique.get(def.as_str()) else { continue }; + line_with_defs = self + .def_regex_delimited + .replace(&line_with_defs, def.value_as_string()) + .to_string(); } final_string.push_str(&line_with_defs); final_string.push('\n'); diff --git a/crates/bevy_render/src/renderer/graph_runner.rs b/crates/bevy_render/src/renderer/graph_runner.rs index 1513d1c4e5697..78314fb818994 100644 --- a/crates/bevy_render/src/renderer/graph_runner.rs +++ b/crates/bevy_render/src/renderer/graph_runner.rs @@ -101,23 +101,22 @@ impl RenderGraphRunner { if let Some(input_node) = graph.get_input_node() { let mut input_values: SmallVec<[SlotValue; 4]> = SmallVec::new(); for (i, input_slot) in input_node.input_slots.iter().enumerate() { - if let Some(input_value) = inputs.get(i) { - if input_slot.slot_type != input_value.slot_type() { - return Err(RenderGraphRunnerError::MismatchedInputSlotType { - slot_index: i, - actual: input_value.slot_type(), - expected: input_slot.slot_type, - label: input_slot.name.clone().into(), - }); - } - input_values.push(input_value.clone()); - } else { + let Some(input_value) = inputs.get(i) else { return Err(RenderGraphRunnerError::MissingInput { slot_index: i, slot_name: input_slot.name.clone(), graph_name: graph_name.clone(), }); + }; + if input_slot.slot_type != input_value.slot_type() { + return Err(RenderGraphRunnerError::MismatchedInputSlotType { + slot_index: i, + actual: input_value.slot_type(), + expected: input_slot.slot_type, + label: input_slot.name.clone().into(), + }); } + input_values.push(input_value.clone()); } node_outputs.insert(input_node.id, input_values); @@ -204,16 +203,15 @@ impl RenderGraphRunner { let mut values: SmallVec<[SlotValue; 4]> = SmallVec::new(); for (i, output) in outputs.into_iter().enumerate() { - if let Some(value) = output { - values.push(value); - } else { + let Some(value) = output else { let empty_slot = node_state.output_slots.get_slot(i).unwrap(); return Err(RenderGraphRunnerError::EmptyNodeOutputSlot { type_name: node_state.type_name, slot_index: i, slot_name: empty_slot.name.clone(), }); - } + }; + values.push(value); } node_outputs.insert(node_state.id, values); diff --git a/crates/bevy_render/src/renderer/mod.rs b/crates/bevy_render/src/renderer/mod.rs index aa362a3d9b2ed..cedcf79f01e53 100644 --- a/crates/bevy_render/src/renderer/mod.rs +++ b/crates/bevy_render/src/renderer/mod.rs @@ -62,11 +62,9 @@ pub fn render_system(world: &mut World) { let mut windows = world.resource_mut::(); for window in windows.values_mut() { - if let Some(texture_view) = window.swap_chain_texture.take() { - if let Some(surface_texture) = texture_view.take_surface_texture() { - surface_texture.present(); - } - } + let Some(texture_view) = window.swap_chain_texture.take() else { continue }; + let Some(surface_texture) = texture_view.take_surface_texture() else { continue }; + surface_texture.present(); } #[cfg(feature = "tracing-tracy")] diff --git a/crates/bevy_render/src/view/mod.rs b/crates/bevy_render/src/view/mod.rs index bc0c12b023135..8e783e82490af 100644 --- a/crates/bevy_render/src/view/mod.rs +++ b/crates/bevy_render/src/view/mod.rs @@ -285,82 +285,79 @@ fn prepare_view_targets( ) { let mut textures = HashMap::default(); for (entity, camera, view) in cameras.iter() { - if let Some(target_size) = camera.physical_target_size { - if let (Some(out_texture_view), Some(out_texture_format)) = ( - camera.target.get_texture_view(&windows, &images), - camera.target.get_texture_format(&windows, &images), - ) { - let size = Extent3d { - width: target_size.x, - height: target_size.y, - depth_or_array_layers: 1, - }; + let Some(target_size) = camera.physical_target_size else { continue }; + let (Some(out_texture_view), Some(out_texture_format)) = ( + camera.target.get_texture_view(&windows, &images), + camera.target.get_texture_format(&windows, &images), + ) else { continue }; + let size = Extent3d { + width: target_size.x, + height: target_size.y, + depth_or_array_layers: 1, + }; - let main_texture_format = if view.hdr { - ViewTarget::TEXTURE_FORMAT_HDR - } else { - TextureFormat::bevy_default() - }; + let main_texture_format = if view.hdr { + ViewTarget::TEXTURE_FORMAT_HDR + } else { + TextureFormat::bevy_default() + }; - let main_textures = textures - .entry((camera.target.clone(), view.hdr)) - .or_insert_with(|| { - let descriptor = TextureDescriptor { - label: None, - size, - mip_level_count: 1, - sample_count: 1, - dimension: TextureDimension::D2, - format: main_texture_format, - usage: TextureUsages::RENDER_ATTACHMENT - | TextureUsages::TEXTURE_BINDING, - }; - MainTargetTextures { - a: texture_cache - .get( - &render_device, - TextureDescriptor { - label: Some("main_texture_a"), - ..descriptor - }, - ) - .default_view, - b: texture_cache - .get( - &render_device, - TextureDescriptor { - label: Some("main_texture_b"), - ..descriptor - }, - ) - .default_view, - sampled: (msaa.samples > 1).then(|| { - texture_cache - .get( - &render_device, - TextureDescriptor { - label: Some("main_texture_sampled"), - size, - mip_level_count: 1, - sample_count: msaa.samples, - dimension: TextureDimension::D2, - format: main_texture_format, - usage: TextureUsages::RENDER_ATTACHMENT, - }, - ) - .default_view - }), - } - }); - - commands.entity(entity).insert(ViewTarget { - main_textures: main_textures.clone(), - main_texture_format, - main_texture: AtomicUsize::new(0), - out_texture: out_texture_view.clone(), - out_texture_format, - }); - } - } + let main_textures = textures + .entry((camera.target.clone(), view.hdr)) + .or_insert_with(|| { + let descriptor = TextureDescriptor { + label: None, + size, + mip_level_count: 1, + sample_count: 1, + dimension: TextureDimension::D2, + format: main_texture_format, + usage: TextureUsages::RENDER_ATTACHMENT | TextureUsages::TEXTURE_BINDING, + }; + MainTargetTextures { + a: texture_cache + .get( + &render_device, + TextureDescriptor { + label: Some("main_texture_a"), + ..descriptor + }, + ) + .default_view, + b: texture_cache + .get( + &render_device, + TextureDescriptor { + label: Some("main_texture_b"), + ..descriptor + }, + ) + .default_view, + sampled: (msaa.samples > 1).then(|| { + texture_cache + .get( + &render_device, + TextureDescriptor { + label: Some("main_texture_sampled"), + size, + mip_level_count: 1, + sample_count: msaa.samples, + dimension: TextureDimension::D2, + format: main_texture_format, + usage: TextureUsages::RENDER_ATTACHMENT, + }, + ) + .default_view + }), + } + }); + + commands.entity(entity).insert(ViewTarget { + main_textures: main_textures.clone(), + main_texture_format, + main_texture: AtomicUsize::new(0), + out_texture: out_texture_view.clone(), + out_texture_format, + }); } } diff --git a/crates/bevy_render/src/view/visibility/mod.rs b/crates/bevy_render/src/view/visibility/mod.rs index e4a57217c1bc1..ba21f41b0fd52 100644 --- a/crates/bevy_render/src/view/visibility/mod.rs +++ b/crates/bevy_render/src/view/visibility/mod.rs @@ -268,11 +268,9 @@ pub fn calculate_bounds( without_aabb: Query<(Entity, &Handle), (Without, Without)>, ) { for (entity, mesh_handle) in &without_aabb { - if let Some(mesh) = meshes.get(mesh_handle) { - if let Some(aabb) = mesh.compute_aabb() { - commands.entity(entity).insert(aabb); - } - } + let Some(mesh) = meshes.get(mesh_handle) else { continue }; + let Some(aabb) = mesh.compute_aabb() else { continue }; + commands.entity(entity).insert(aabb); } } @@ -308,16 +306,15 @@ fn visibility_propagate_system( // reset "view" visibility here ... if this entity should be drawn a future system should set this to true computed_visibility .reset(visibility == Visibility::Inherited || visibility == Visibility::Visible); - if let Some(children) = children { - for child in children.iter() { - let _ = propagate_recursive( - computed_visibility.is_visible_in_hierarchy(), - &mut visibility_query, - &children_query, - *child, - entity, - ); - } + let Some(children) = children else { continue }; + for child in children.iter() { + let _ = propagate_recursive( + computed_visibility.is_visible_in_hierarchy(), + &mut visibility_query, + &children_query, + *child, + entity, + ); } } } diff --git a/crates/bevy_scene/src/dynamic_scene_builder.rs b/crates/bevy_scene/src/dynamic_scene_builder.rs index 5ea65a8714eab..392b8f7ab258e 100644 --- a/crates/bevy_scene/src/dynamic_scene_builder.rs +++ b/crates/bevy_scene/src/dynamic_scene_builder.rs @@ -125,18 +125,15 @@ impl<'w> DynamicSceneBuilder<'w> { }; for component_id in self.original_world.entity(entity).archetype().components() { - let reflect_component = self + let Some(reflect_component) = self .original_world .components() .get_info(component_id) .and_then(|info| type_registry.get(info.type_id().unwrap())) - .and_then(|registration| registration.data::()); + .and_then(|registration| registration.data::()) else { continue }; - if let Some(reflect_component) = reflect_component { - if let Some(component) = reflect_component.reflect(self.original_world, entity) - { - entry.components.push(component.clone_value()); - } + if let Some(component) = reflect_component.reflect(self.original_world, entity) { + entry.components.push(component.clone_value()); } } self.extracted_scene.insert(index, entry); diff --git a/crates/bevy_scene/src/scene_spawner.rs b/crates/bevy_scene/src/scene_spawner.rs index f8f581a609d65..8a71f8fe3233c 100644 --- a/crates/bevy_scene/src/scene_spawner.rs +++ b/crates/bevy_scene/src/scene_spawner.rs @@ -190,16 +190,10 @@ impl SceneSpawner { scene_handles: &[Handle], ) -> Result<(), SceneSpawnError> { for scene_handle in scene_handles { - if let Some(spawned_instances) = self.spawned_dynamic_scenes.get(scene_handle) { - for instance_id in spawned_instances { - if let Some(instance_info) = self.spawned_instances.get_mut(instance_id) { - Self::spawn_dynamic_internal( - world, - scene_handle, - &mut instance_info.entity_map, - )?; - } - } + let Some(spawned_instances) = self.spawned_dynamic_scenes.get(scene_handle) else { continue }; + for instance_id in spawned_instances { + let Some(instance_info) = self.spawned_instances.get_mut(instance_id) else { continue }; + Self::spawn_dynamic_internal(world, scene_handle, &mut instance_info.entity_map)?; } } Ok(()) @@ -265,28 +259,28 @@ impl SceneSpawner { let scenes_with_parent = std::mem::take(&mut self.scenes_with_parent); for (instance_id, parent) in scenes_with_parent { - if let Some(instance) = self.spawned_instances.get(&instance_id) { - for entity in instance.entity_map.values() { - // Add the `Parent` component to the scene root, and update the `Children` component of - // the scene parent - if !world - .get_entity(entity) - // This will filter only the scene root entity, as all other from the - // scene have a parent - .map(|entity| entity.contains::()) - // Default is true so that it won't run on an entity that wouldn't exist anymore - // this case shouldn't happen anyway - .unwrap_or(true) - { - AddChild { - parent, - child: entity, - } - .write(world); + let Some(instance) = self.spawned_instances.get(&instance_id) else { + self.scenes_with_parent.push((instance_id, parent)); + continue; + }; + for entity in instance.entity_map.values() { + // Add the `Parent` component to the scene root, and update the `Children` component of + // the scene parent + if !world + .get_entity(entity) + // This will filter only the scene root entity, as all other from the + // scene have a parent + .map(|entity| entity.contains::()) + // Default is true so that it won't run on an entity that wouldn't exist anymore + // this case shouldn't happen anyway + .unwrap_or(true) + { + AddChild { + parent, + child: entity, } + .write(world); } - } else { - self.scenes_with_parent.push((instance_id, parent)); } } } diff --git a/crates/bevy_sprite/src/dynamic_texture_atlas_builder.rs b/crates/bevy_sprite/src/dynamic_texture_atlas_builder.rs index 1155e0c5e23ce..271a9ef89571c 100644 --- a/crates/bevy_sprite/src/dynamic_texture_atlas_builder.rs +++ b/crates/bevy_sprite/src/dynamic_texture_atlas_builder.rs @@ -26,16 +26,12 @@ impl DynamicTextureAtlasBuilder { let allocation = self.atlas_allocator.allocate(size2( texture.texture_descriptor.size.width as i32 + self.padding, texture.texture_descriptor.size.height as i32 + self.padding, - )); - if let Some(allocation) = allocation { - let atlas_texture = textures.get_mut(&texture_atlas.texture).unwrap(); - self.place_texture(atlas_texture, allocation, texture); - let mut rect: Rect = to_rect(allocation.rectangle); - rect.max -= self.padding as f32; - Some(texture_atlas.add_texture(rect)) - } else { - None - } + ))?; + let atlas_texture = textures.get_mut(&texture_atlas.texture).unwrap(); + self.place_texture(atlas_texture, allocation, texture); + let mut rect: Rect = to_rect(allocation.rectangle); + rect.max -= self.padding as f32; + Some(texture_atlas.add_texture(rect)) } // fn resize( diff --git a/crates/bevy_sprite/src/mesh2d/material.rs b/crates/bevy_sprite/src/mesh2d/material.rs index 0a2a0b35ee116..3c760f948e2fa 100644 --- a/crates/bevy_sprite/src/mesh2d/material.rs +++ b/crates/bevy_sprite/src/mesh2d/material.rs @@ -342,48 +342,44 @@ pub fn queue_material2d_meshes( } for visible_entity in &visible_entities.entities { - if let Ok((material2d_handle, mesh2d_handle, mesh2d_uniform)) = - material2d_meshes.get(*visible_entity) - { - if let Some(material2d) = render_materials.get(material2d_handle) { - if let Some(mesh) = render_meshes.get(&mesh2d_handle.0) { - let mesh_key = view_key - | Mesh2dPipelineKey::from_primitive_topology(mesh.primitive_topology); - - let pipeline_id = pipelines.specialize( - &mut pipeline_cache, - &material2d_pipeline, - Material2dKey { - mesh_key, - bind_group_data: material2d.key.clone(), - }, - &mesh.layout, - ); - - let pipeline_id = match pipeline_id { - Ok(id) => id, - Err(err) => { - error!("{}", err); - continue; - } - }; - - let mesh_z = mesh2d_uniform.transform.w_axis.z; - transparent_phase.add(Transparent2d { - entity: *visible_entity, - draw_function: draw_transparent_pbr, - pipeline: pipeline_id, - // NOTE: Back-to-front ordering for transparent with ascending sort means far should have the - // lowest sort key and getting closer should increase. As we have - // -z in front of the camera, the largest distance is -far with values increasing toward the - // camera. As such we can just use mesh_z as the distance - sort_key: FloatOrd(mesh_z), - // This material is not batched - batch_range: None, - }); - } + let Ok((material2d_handle, mesh2d_handle, mesh2d_uniform)) = + material2d_meshes.get(*visible_entity) else { continue }; + let Some(material2d) = render_materials.get(material2d_handle) else { continue }; + let Some(mesh) = render_meshes.get(&mesh2d_handle.0) else { continue }; + let mesh_key = + view_key | Mesh2dPipelineKey::from_primitive_topology(mesh.primitive_topology); + + let pipeline_id = pipelines.specialize( + &mut pipeline_cache, + &material2d_pipeline, + Material2dKey { + mesh_key, + bind_group_data: material2d.key.clone(), + }, + &mesh.layout, + ); + + let pipeline_id = match pipeline_id { + Ok(id) => id, + Err(err) => { + error!("{}", err); + continue; } - } + }; + + let mesh_z = mesh2d_uniform.transform.w_axis.z; + transparent_phase.add(Transparent2d { + entity: *visible_entity, + draw_function: draw_transparent_pbr, + pipeline: pipeline_id, + // NOTE: Back-to-front ordering for transparent with ascending sort means far should have the + // lowest sort key and getting closer should increase. As we have + // -z in front of the camera, the largest distance is -far with values increasing toward the + // camera. As such we can just use mesh_z as the distance + sort_key: FloatOrd(mesh_z), + // This material is not batched + batch_range: None, + }); } } } diff --git a/crates/bevy_sprite/src/mesh2d/mesh.rs b/crates/bevy_sprite/src/mesh2d/mesh.rs index 03e9f468aaa21..ffa1e38d263b8 100644 --- a/crates/bevy_sprite/src/mesh2d/mesh.rs +++ b/crates/bevy_sprite/src/mesh2d/mesh.rs @@ -441,18 +441,17 @@ pub fn queue_mesh2d_bind_group( render_device: Res, mesh2d_uniforms: Res>, ) { - if let Some(binding) = mesh2d_uniforms.uniforms().binding() { - commands.insert_resource(Mesh2dBindGroup { - value: render_device.create_bind_group(&BindGroupDescriptor { - entries: &[BindGroupEntry { - binding: 0, - resource: binding, - }], - label: Some("mesh2d_bind_group"), - layout: &mesh2d_pipeline.mesh_layout, - }), - }); - } + let Some(binding) = mesh2d_uniforms.uniforms().binding() else { return }; + commands.insert_resource(Mesh2dBindGroup { + value: render_device.create_bind_group(&BindGroupDescriptor { + entries: &[BindGroupEntry { + binding: 0, + resource: binding, + }], + label: Some("mesh2d_bind_group"), + layout: &mesh2d_pipeline.mesh_layout, + }), + }); } #[derive(Component)] diff --git a/crates/bevy_text/src/font_atlas.rs b/crates/bevy_text/src/font_atlas.rs index be1903c121b36..0ceca63d54add 100644 --- a/crates/bevy_text/src/font_atlas.rs +++ b/crates/bevy_text/src/font_atlas.rs @@ -93,15 +93,13 @@ impl FontAtlas { texture: &Image, ) -> bool { let texture_atlas = texture_atlases.get_mut(&self.texture_atlas).unwrap(); - if let Some(index) = - self.dynamic_texture_atlas_builder - .add_texture(texture_atlas, textures, texture) - { - self.glyph_to_atlas_index - .insert((glyph_id, subpixel_offset), index); - true - } else { - false - } + self.dynamic_texture_atlas_builder + .add_texture(texture_atlas, textures, texture) + .map(|index| { + self.glyph_to_atlas_index + .insert((glyph_id, subpixel_offset), index); + true + }) + .unwrap_or(false) } } diff --git a/crates/bevy_text/src/glyph_brush.rs b/crates/bevy_text/src/glyph_brush.rs index b3b8e3d79f018..5380cb13a76ab 100644 --- a/crates/bevy_text/src/glyph_brush.rs +++ b/crates/bevy_text/src/glyph_brush.rs @@ -106,48 +106,49 @@ impl GlyphBrush { let glyph_position = glyph.position; let adjust = GlyphPlacementAdjuster::new(&mut glyph); let section_data = sections_data[sg.section_index]; - if let Some(outlined_glyph) = section_data.1.font.outline_glyph(glyph) { - let bounds = outlined_glyph.px_bounds(); - let handle_font_atlas: Handle = section_data.0.cast_weak(); - let font_atlas_set = font_atlas_set_storage - .get_or_insert_with(handle_font_atlas, FontAtlasSet::default); - - let atlas_info = font_atlas_set - .get_glyph_atlas_info(section_data.2, glyph_id, glyph_position) - .map(Ok) - .unwrap_or_else(|| { - font_atlas_set.add_glyph_to_atlas(texture_atlases, textures, outlined_glyph) - })?; - - if !text_settings.allow_dynamic_font_size - && !font_atlas_warning.warned - && font_atlas_set.num_font_atlases() > text_settings.max_font_atlases.get() - { - warn!("warning[B0005]: Number of font atlases has exceeded the maximum of {}. Performance and memory usage may suffer.", text_settings.max_font_atlases.get()); - font_atlas_warning.warned = true; - } - - let texture_atlas = texture_atlases.get(&atlas_info.texture_atlas).unwrap(); - let glyph_rect = texture_atlas.textures[atlas_info.glyph_index]; - let size = Vec2::new(glyph_rect.width(), glyph_rect.height()); - - let x = bounds.min.x + size.x / 2.0 - min_x; - - let y = match y_axis_orientation { - YAxisOrientation::BottomToTop => max_y - bounds.max.y + size.y / 2.0, - YAxisOrientation::TopToBottom => bounds.min.y + size.y / 2.0 - min_y, - }; - - let position = adjust.position(Vec2::new(x, y)); - - positioned_glyphs.push(PositionedGlyph { - position, - size, - atlas_info, - section_index: sg.section_index, - byte_index, - }); + + let Some(outlined_glyph) = section_data.1.font.outline_glyph(glyph) else { continue }; + + let bounds = outlined_glyph.px_bounds(); + let handle_font_atlas: Handle = section_data.0.cast_weak(); + let font_atlas_set = + font_atlas_set_storage.get_or_insert_with(handle_font_atlas, FontAtlasSet::default); + + let atlas_info = font_atlas_set + .get_glyph_atlas_info(section_data.2, glyph_id, glyph_position) + .map(Ok) + .unwrap_or_else(|| { + font_atlas_set.add_glyph_to_atlas(texture_atlases, textures, outlined_glyph) + })?; + + if !text_settings.allow_dynamic_font_size + && !font_atlas_warning.warned + && font_atlas_set.num_font_atlases() > text_settings.max_font_atlases.get() + { + warn!("warning[B0005]: Number of font atlases has exceeded the maximum of {}. Performance and memory usage may suffer.", text_settings.max_font_atlases.get()); + font_atlas_warning.warned = true; } + + let texture_atlas = texture_atlases.get(&atlas_info.texture_atlas).unwrap(); + let glyph_rect = texture_atlas.textures[atlas_info.glyph_index]; + let size = Vec2::new(glyph_rect.width(), glyph_rect.height()); + + let x = bounds.min.x + size.x / 2.0 - min_x; + + let y = match y_axis_orientation { + YAxisOrientation::BottomToTop => max_y - bounds.max.y + size.y / 2.0, + YAxisOrientation::TopToBottom => bounds.min.y + size.y / 2.0 - min_y, + }; + + let position = adjust.position(Vec2::new(x, y)); + + positioned_glyphs.push(PositionedGlyph { + position, + size, + atlas_info, + section_index: sg.section_index, + byte_index, + }); } Ok(positioned_glyphs) } diff --git a/crates/bevy_time/src/fixed_timestep.rs b/crates/bevy_time/src/fixed_timestep.rs index 8a63f67f92bb6..90dbbed909211 100644 --- a/crates/bevy_time/src/fixed_timestep.rs +++ b/crates/bevy_time/src/fixed_timestep.rs @@ -208,16 +208,15 @@ impl System for FixedTimestep { self.state.clone(), ))); self.internal_system.initialize(world); - if let Some(ref label) = self.state.label { - let mut fixed_timesteps = world.resource_mut::(); - fixed_timesteps.fixed_timesteps.insert( - label.clone(), - FixedTimestepState { - accumulator: 0.0, - step: self.state.step, - }, - ); - } + let Some(ref label) = self.state.label else { return }; + let mut fixed_timesteps = world.resource_mut::(); + fixed_timesteps.fixed_timesteps.insert( + label.clone(), + FixedTimestepState { + accumulator: 0.0, + step: self.state.step, + }, + ); } fn update_archetype_component_access(&mut self, world: &World) { diff --git a/crates/bevy_ui/src/focus.rs b/crates/bevy_ui/src/focus.rs index aa5327c13ad3a..447971f29dc08 100644 --- a/crates/bevy_ui/src/focus.rs +++ b/crates/bevy_ui/src/focus.rs @@ -114,10 +114,9 @@ pub fn ui_focus_system( mouse_button_input.just_released(MouseButton::Left) || touches_input.any_just_released(); if mouse_released { for node in node_query.iter_mut() { - if let Some(mut interaction) = node.interaction { - if *interaction == Interaction::Clicked { - *interaction = Interaction::None; - } + let Some(mut interaction) = node.interaction else { continue }; + if *interaction == Interaction::Clicked { + *interaction = Interaction::None; } } } @@ -239,11 +238,10 @@ pub fn ui_focus_system( // `moused_over_nodes` after the previous loop is exited. let mut iter = node_query.iter_many_mut(moused_over_nodes); while let Some(node) = iter.fetch_next() { - if let Some(mut interaction) = node.interaction { - // don't reset clicked nodes because they're handled separately - if *interaction != Interaction::Clicked { - interaction.set_if_neq(Interaction::None); - } + let Some(mut interaction) = node.interaction else { continue }; + // don't reset clicked nodes because they're handled separately + if *interaction != Interaction::Clicked { + interaction.set_if_neq(Interaction::None); } } } diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index 595896c1fdfec..e6ddf7d39433e 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -450,28 +450,29 @@ pub fn prepare_uinodes( // Calculate the effect of clipping // Note: this won't work with rotation/scaling, but that's much more complex (may need more that 2 quads) - let positions_diff = if let Some(clip) = extracted_uinode.clip { - [ - Vec2::new( - f32::max(clip.min.x - positions[0].x, 0.), - f32::max(clip.min.y - positions[0].y, 0.), - ), - Vec2::new( - f32::min(clip.max.x - positions[1].x, 0.), - f32::max(clip.min.y - positions[1].y, 0.), - ), - Vec2::new( - f32::min(clip.max.x - positions[2].x, 0.), - f32::min(clip.max.y - positions[2].y, 0.), - ), - Vec2::new( - f32::max(clip.min.x - positions[3].x, 0.), - f32::min(clip.max.y - positions[3].y, 0.), - ), - ] - } else { - [Vec2::ZERO; 4] - }; + let positions_diff = extracted_uinode + .clip + .map(|clip| { + [ + Vec2::new( + f32::max(clip.min.x - positions[0].x, 0.), + f32::max(clip.min.y - positions[0].y, 0.), + ), + Vec2::new( + f32::min(clip.max.x - positions[1].x, 0.), + f32::max(clip.min.y - positions[1].y, 0.), + ), + Vec2::new( + f32::min(clip.max.x - positions[2].x, 0.), + f32::min(clip.max.y - positions[2].y, 0.), + ), + Vec2::new( + f32::max(clip.min.x - positions[3].x, 0.), + f32::min(clip.max.y - positions[3].y, 0.), + ), + ] + }) + .unwrap_or([Vec2::ZERO; 4]); let positions_clipped = [ positions[0] + positions_diff[0].extend(0.), @@ -579,50 +580,49 @@ pub fn queue_uinodes( }; } - if let Some(view_binding) = view_uniforms.uniforms.binding() { - ui_meta.view_bind_group = Some(render_device.create_bind_group(&BindGroupDescriptor { - entries: &[BindGroupEntry { - binding: 0, - resource: view_binding, - }], - label: Some("ui_view_bind_group"), - layout: &ui_pipeline.view_layout, - })); - let draw_ui_function = draw_functions.read().id::(); - for (view, mut transparent_phase) in &mut views { - let pipeline = pipelines.specialize( - &mut pipeline_cache, - &ui_pipeline, - UiPipelineKey { hdr: view.hdr }, - ); - for (entity, batch) in &ui_batches { - image_bind_groups - .values - .entry(batch.image.clone_weak()) - .or_insert_with(|| { - let gpu_image = gpu_images.get(&batch.image).unwrap(); - render_device.create_bind_group(&BindGroupDescriptor { - entries: &[ - BindGroupEntry { - binding: 0, - resource: BindingResource::TextureView(&gpu_image.texture_view), - }, - BindGroupEntry { - binding: 1, - resource: BindingResource::Sampler(&gpu_image.sampler), - }, - ], - label: Some("ui_material_bind_group"), - layout: &ui_pipeline.image_layout, - }) - }); - transparent_phase.add(TransparentUi { - draw_function: draw_ui_function, - pipeline, - entity, - sort_key: FloatOrd(batch.z), + let Some(view_binding) = view_uniforms.uniforms.binding() else { return }; + ui_meta.view_bind_group = Some(render_device.create_bind_group(&BindGroupDescriptor { + entries: &[BindGroupEntry { + binding: 0, + resource: view_binding, + }], + label: Some("ui_view_bind_group"), + layout: &ui_pipeline.view_layout, + })); + let draw_ui_function = draw_functions.read().id::(); + for (view, mut transparent_phase) in &mut views { + let pipeline = pipelines.specialize( + &mut pipeline_cache, + &ui_pipeline, + UiPipelineKey { hdr: view.hdr }, + ); + for (entity, batch) in &ui_batches { + image_bind_groups + .values + .entry(batch.image.clone_weak()) + .or_insert_with(|| { + let gpu_image = gpu_images.get(&batch.image).unwrap(); + render_device.create_bind_group(&BindGroupDescriptor { + entries: &[ + BindGroupEntry { + binding: 0, + resource: BindingResource::TextureView(&gpu_image.texture_view), + }, + BindGroupEntry { + binding: 1, + resource: BindingResource::Sampler(&gpu_image.sampler), + }, + ], + label: Some("ui_material_bind_group"), + layout: &ui_pipeline.image_layout, + }) }); - } + transparent_phase.add(TransparentUi { + draw_function: draw_ui_function, + pipeline, + entity, + sort_key: FloatOrd(batch.z), + }); } } } diff --git a/crates/bevy_ui/src/widget/image.rs b/crates/bevy_ui/src/widget/image.rs index fa2e011232cec..b27d7364b3753 100644 --- a/crates/bevy_ui/src/widget/image.rs +++ b/crates/bevy_ui/src/widget/image.rs @@ -13,16 +13,15 @@ pub fn update_image_calculated_size_system( mut query: Query<(&mut CalculatedSize, &UiImage), Without>, ) { for (mut calculated_size, image) in &mut query { - if let Some(texture) = textures.get(&image.texture) { - let size = Size { - width: Val::Px(texture.texture_descriptor.size.width as f32), - height: Val::Px(texture.texture_descriptor.size.height as f32), - }; - // Update only if size has changed to avoid needless layout calculations - if size != calculated_size.size { - calculated_size.size = size; - calculated_size.preserve_aspect_ratio = true; - } + let Some(texture) = textures.get(&image.texture) else { continue }; + let size = Size { + width: Val::Px(texture.texture_descriptor.size.width as f32), + height: Val::Px(texture.texture_descriptor.size.height as f32), + }; + // Update only if size has changed to avoid needless layout calculations + if size != calculated_size.size { + calculated_size.size = size; + calculated_size.preserve_aspect_ratio = true; } } } diff --git a/crates/bevy_ui/src/widget/text.rs b/crates/bevy_ui/src/widget/text.rs index 8455a9455af13..1f598a4065b3a 100644 --- a/crates/bevy_ui/src/widget/text.rs +++ b/crates/bevy_ui/src/widget/text.rs @@ -71,11 +71,10 @@ pub fn text_system( ) { // TODO: This should support window-independent scale settings. // See https://github.com/bevyengine/bevy/issues/5621 - let scale_factor = if let Some(window) = windows.get_primary() { - window.scale_factor() * ui_scale.scale - } else { - ui_scale.scale - }; + let scale_factor = windows + .get_primary() + .map(|window| window.scale_factor() * ui_scale.scale) + .unwrap_or(ui_scale.scale); let inv_scale_factor = 1. / scale_factor; diff --git a/crates/bevy_utils/src/label.rs b/crates/bevy_utils/src/label.rs index 6c504b0283a30..51e56483e199f 100644 --- a/crates/bevy_utils/src/label.rs +++ b/crates/bevy_utils/src/label.rs @@ -27,10 +27,11 @@ where } fn dyn_eq(&self, other: &dyn DynEq) -> bool { - if let Some(other) = other.as_any().downcast_ref::() { - return self == other; - } - false + other + .as_any() + .downcast_ref::() + .map(|other| self == other) + .unwrap_or(false) } } diff --git a/crates/bevy_window/src/windows.rs b/crates/bevy_window/src/windows.rs index 5ffbf524c1423..3d4624d1029ae 100644 --- a/crates/bevy_window/src/windows.rs +++ b/crates/bevy_window/src/windows.rs @@ -65,11 +65,9 @@ impl Windows { /// Returns the scale factor for the [`Window`] of `id`, or `1.0` if the window does not exist. pub fn scale_factor(&self, id: WindowId) -> f64 { - if let Some(window) = self.get(id) { - window.scale_factor() - } else { - 1.0 - } + self.get(id) + .map(|window| window.scale_factor()) + .unwrap_or(1.0) } /// An iterator over all registered [`Window`]s. diff --git a/examples/2d/mesh2d_manual.rs b/examples/2d/mesh2d_manual.rs index 4147a4a4966f4..69ef1bb942d65 100644 --- a/examples/2d/mesh2d_manual.rs +++ b/examples/2d/mesh2d_manual.rs @@ -334,29 +334,27 @@ pub fn queue_colored_mesh2d( // Queue all entities visible to that view for visible_entity in &visible_entities.entities { - if let Ok((mesh2d_handle, mesh2d_uniform)) = colored_mesh2d.get(*visible_entity) { - // Get our specialized pipeline - let mut mesh2d_key = mesh_key; - if let Some(mesh) = render_meshes.get(&mesh2d_handle.0) { - mesh2d_key |= - Mesh2dPipelineKey::from_primitive_topology(mesh.primitive_topology); - } - - let pipeline_id = - pipelines.specialize(&mut pipeline_cache, &colored_mesh2d_pipeline, mesh2d_key); - - let mesh_z = mesh2d_uniform.transform.w_axis.z; - transparent_phase.add(Transparent2d { - entity: *visible_entity, - draw_function: draw_colored_mesh2d, - pipeline: pipeline_id, - // The 2d render items are sorted according to their z value before rendering, - // in order to get correct transparency - sort_key: FloatOrd(mesh_z), - // This material is not batched - batch_range: None, - }); + let Ok((mesh2d_handle, mesh2d_uniform)) = colored_mesh2d.get(*visible_entity) else { continue }; + // Get our specialized pipeline + let mut mesh2d_key = mesh_key; + if let Some(mesh) = render_meshes.get(&mesh2d_handle.0) { + mesh2d_key |= Mesh2dPipelineKey::from_primitive_topology(mesh.primitive_topology); } + + let pipeline_id = + pipelines.specialize(&mut pipeline_cache, &colored_mesh2d_pipeline, mesh2d_key); + + let mesh_z = mesh2d_uniform.transform.w_axis.z; + transparent_phase.add(Transparent2d { + entity: *visible_entity, + draw_function: draw_colored_mesh2d, + pipeline: pipeline_id, + // The 2d render items are sorted according to their z value before rendering, + // in order to get correct transparency + sort_key: FloatOrd(mesh_z), + // This material is not batched + batch_range: None, + }); } } } diff --git a/examples/3d/skybox.rs b/examples/3d/skybox.rs index c9dadafd5b8f1..341edea8cd93c 100644 --- a/examples/3d/skybox.rs +++ b/examples/3d/skybox.rs @@ -168,10 +168,9 @@ fn asset_loaded( // spawn cube let mut updated = false; for handle in cubes.iter() { - if let Some(material) = cubemap_materials.get_mut(handle) { - updated = true; - material.base_color_texture = Some(cubemap.image_handle.clone_weak()); - } + let Some(material) = cubemap_materials.get_mut(handle) else { continue }; + updated = true; + material.base_color_texture = Some(cubemap.image_handle.clone_weak()); } if !updated { commands.spawn(MaterialMeshBundle:: { diff --git a/examples/async_tasks/async_compute.rs b/examples/async_tasks/async_compute.rs index d0f4466d76eaf..69223ac5be391 100644 --- a/examples/async_tasks/async_compute.rs +++ b/examples/async_tasks/async_compute.rs @@ -88,18 +88,17 @@ fn handle_tasks( box_material_handle: Res, ) { for (entity, mut task) in &mut transform_tasks { - if let Some(transform) = future::block_on(future::poll_once(&mut task.0)) { - // Add our new PbrBundle of components to our tagged entity - commands.entity(entity).insert(PbrBundle { - mesh: box_mesh_handle.clone(), - material: box_material_handle.clone(), - transform, - ..default() - }); - - // Task is complete, so remove task component from entity - commands.entity(entity).remove::(); - } + let Some(transform) = future::block_on(future::poll_once(&mut task.0)) else { continue }; + // Add our new PbrBundle of components to our tagged entity + commands.entity(entity).insert(PbrBundle { + mesh: box_mesh_handle.clone(), + material: box_material_handle.clone(), + transform, + ..default() + }); + + // Task is complete, so remove task component from entity + commands.entity(entity).remove::(); } } diff --git a/examples/audio/audio_control.rs b/examples/audio/audio_control.rs index 85598082276a7..4a05a5d626254 100644 --- a/examples/audio/audio_control.rs +++ b/examples/audio/audio_control.rs @@ -53,11 +53,10 @@ fn volume( audio_sinks: Res>, music_controller: Res, ) { - if let Some(sink) = audio_sinks.get(&music_controller.0) { - if keyboard_input.just_pressed(KeyCode::Plus) { - sink.set_volume(sink.volume() + 0.1); - } else if keyboard_input.just_pressed(KeyCode::Minus) { - sink.set_volume(sink.volume() - 0.1); - } + let Some(sink) = audio_sinks.get(&music_controller.0) else { return }; + if keyboard_input.just_pressed(KeyCode::Plus) { + sink.set_volume(sink.volume() + 0.1); + } else if keyboard_input.just_pressed(KeyCode::Minus) { + sink.set_volume(sink.volume() - 0.1); } } diff --git a/examples/games/alien_cake_addict.rs b/examples/games/alien_cake_addict.rs index c0267af6077a4..0a0464eaee068 100644 --- a/examples/games/alien_cake_addict.rs +++ b/examples/games/alien_cake_addict.rs @@ -353,13 +353,11 @@ fn spawn_bonus( // let the cake turn on itself fn rotate_bonus(game: Res, time: Res