Skip to main content

DirtyWireframeSpecializations

Struct DirtyWireframeSpecializations 

Source
pub struct DirtyWireframeSpecializations(pub DirtySpecializations);
Available on crate feature bevy_render only.
Expand description

Stores information about all entities that have changed in such a way as to potentially require their wireframe pipelines to be re-specialized.

This is separate from DirtySpecializations because a single entity can have both a mesh and a wireframe on it, and the pipelines are treated separately.

See DirtySpecializations for more information.

Tuple Fields§

§0: DirtySpecializations

Methods from Deref<Target = DirtySpecializations>§

Source

pub fn must_wipe_specializations_for_view( &self, view: RetainedViewEntity, ) -> bool

Returns true if the view has changed in such a way that all specialized pipelines for entities visible from it must be regenerated.

Source

pub fn iter_to_despecialize<'a>( &'a self, ) -> impl Iterator<Item = &'a MainEntity>

Iterates over all entities that need their specializations cleared in this frame.

Source

pub fn iter_to_specialize<'a>( &'a self, view: RetainedViewEntity, render_view_visible_mesh_entities: &'a RenderVisibleEntitiesClass, last_frame_view_pending_queues: &'a HashSet<(Entity, MainEntity)>, ) -> impl Iterator<Item = (&'a Entity, &'a MainEntity)>

Iterates over all entities that need to have their pipelines re-specialized this frame.

last_frame_view_pending_queues should be the contents of the ViewPendingQueues::prev_frame list.

Source

pub fn iter_to_dequeue<'a>( &'a self, view: RetainedViewEntity, render_visible_mesh_entities: &'a RenderVisibleEntitiesClass, ) -> impl Iterator<Item = &'a MainEntity>

Iterates over all renderables that should be removed from the phase.

This includes renderables that became invisible this frame, renderables that are in DirtySpecializations::changed_renderables, and renderables that are in DirtySpecializations::removed_renderables. If this view must itself be re-specialized, this will iterate over all visible entities in addition to those that became invisible.

Examples found in repository?
examples/shader_advanced/custom_phase_item.rs (line 266)
229fn queue_custom_phase_item(
230    pipeline_cache: Res<PipelineCache>,
231    mut pipeline: ResMut<CustomPhasePipeline>,
232    mut opaque_render_phases: ResMut<ViewBinnedRenderPhases<Opaque3d>>,
233    opaque_draw_functions: Res<DrawFunctions<Opaque3d>>,
234    views: Query<(&ExtractedView, &RenderVisibleEntities, &Msaa)>,
235    dirty_specializations: Res<DirtySpecializations>,
236    mut pending_custom_phase_item_queues: ResMut<PendingCustomPhaseItemQueues>,
237    mut mesh_instances_queued_this_iteration_scratch_space: Local<MainEntityHashSet>,
238) {
239    let draw_custom_phase_item = opaque_draw_functions
240        .read()
241        .id::<DrawCustomPhaseItemCommands>();
242
243    // Render phases are per-view, so we need to iterate over all views so that
244    // the entity appears in them. (In this example, we have only one view, but
245    // it's good practice to loop over all views anyway.)
246    for (view, view_visible_entities, msaa) in views.iter() {
247        let Some(opaque_phase) = opaque_render_phases.get_mut(&view.retained_view_entity) else {
248            continue;
249        };
250
251        // Fetch the list of visible entities in the `CustomRenderedEntity`
252        // class. If there are no such entities, then we have no entities to
253        // render, and we're done.
254        let Some(render_visible_mesh_entities) =
255            view_visible_entities.get::<CustomRenderedEntity>()
256        else {
257            continue;
258        };
259
260        let view_pending_custom_phase_item_queues =
261            pending_custom_phase_item_queues.prepare_for_new_frame(view.retained_view_entity);
262
263        // First, remove meshes that need to be respecialized, and those that
264        // were removed, from the bins.
265        for &main_entity in dirty_specializations
266            .iter_to_dequeue(view.retained_view_entity, render_visible_mesh_entities)
267        {
268            opaque_phase.remove(main_entity);
269        }
270
271        // Find all the custom rendered entities that are visible from this
272        // view.
273        for (render_entity, main_entity) in dirty_specializations.iter_to_queue(
274            view.retained_view_entity,
275            render_visible_mesh_entities,
276            &view_pending_custom_phase_item_queues.prev_frame,
277            &mut mesh_instances_queued_this_iteration_scratch_space,
278        ) {
279            // Ordinarily, the [`SpecializedRenderPipeline::Key`] would contain
280            // some per-view settings, such as whether the view is HDR, but for
281            // simplicity's sake we simply hard-code the view's characteristics,
282            // with the exception of number of MSAA samples.
283            let Ok(pipeline_id) = pipeline
284                .variants
285                .specialize(&pipeline_cache, CustomPhaseKey(*msaa))
286            else {
287                continue;
288            };
289
290            // Add the custom render item. We use the
291            // [`BinnedRenderPhaseType::NonMesh`] type to skip the special
292            // handling that Bevy has for meshes (preprocessing, indirect
293            // draws, etc.)
294            //
295            // The asset ID is arbitrary; we simply use [`AssetId::default`],
296            // but you can use anything you like. Note that the asset ID need
297            // not be the ID of a [`Mesh`].
298            opaque_phase.add(
299                Opaque3dBatchSetKey {
300                    draw_function: draw_custom_phase_item,
301                    pipeline: pipeline_id,
302                    material_bind_group_index: None,
303                    lightmap_slab: None,
304                    slabs: MeshSlabs::default(),
305                },
306                Opaque3dBinKey {
307                    asset_id: AssetId::<Mesh>::default().untyped(),
308                },
309                (*render_entity, *main_entity),
310                InputUniformIndex::default(),
311                BinnedRenderPhaseType::NonMesh,
312            );
313        }
314    }
315}
More examples
Hide additional examples
examples/shader_advanced/custom_render_phase.rs (line 597)
559fn queue_custom_meshes(
560    custom_draw_functions: Res<DrawFunctions<Stencil3d>>,
561    mut pipelines: ResMut<SpecializedMeshPipelines<StencilPipeline>>,
562    pipeline_cache: Res<PipelineCache>,
563    custom_draw_pipeline: Res<StencilPipeline>,
564    render_meshes: Res<RenderAssets<RenderMesh>>,
565    render_mesh_instances: Res<RenderMeshInstances>,
566    maybe_batched_instance_buffers: Option<
567        Res<BatchedInstanceBuffers<MeshUniform, MeshInputUniform>>,
568    >,
569    mut custom_render_phases: ResMut<ViewSortedRenderPhases<Stencil3d>>,
570    mut views: Query<(&ExtractedView, &RenderVisibleEntities)>,
571    view_key_cache: Res<ViewKeyCache>,
572    dirty_specializations: Res<DirtySpecializations>,
573    mut pending_custom_mesh_queues: ResMut<PendingCustomMeshQueues>,
574    has_marker: Query<(), With<DrawStencil>>,
575    mut mesh_instances_queued_this_iteration_scratch_space: Local<MainEntityHashSet>,
576) {
577    for (view, visible_entities) in &mut views {
578        let Some(custom_phase) = custom_render_phases.get_mut(&view.retained_view_entity) else {
579            continue;
580        };
581        let draw_custom = custom_draw_functions.read().id::<DrawMesh3dStencil>();
582
583        let Some(&view_key) = view_key_cache.get(&view.retained_view_entity) else {
584            continue;
585        };
586
587        // Since our phase can work on any 3d mesh we can reuse the default mesh 3d filter
588        let Some(render_visible_mesh_entities) = visible_entities.get::<Mesh3d>() else {
589            continue;
590        };
591
592        let view_pending_custom_mesh_queues =
593            pending_custom_mesh_queues.prepare_for_new_frame(view.retained_view_entity);
594
595        // First, remove meshes that need to be respecialized, and those that were removed, from the bins.
596        for &main_entity in dirty_specializations
597            .iter_to_dequeue(view.retained_view_entity, render_visible_mesh_entities)
598        {
599            custom_phase.remove(Entity::PLACEHOLDER, main_entity);
600        }
601
602        for (render_entity, visible_entity) in dirty_specializations.iter_to_queue(
603            view.retained_view_entity,
604            render_visible_mesh_entities,
605            &view_pending_custom_mesh_queues.prev_frame,
606            &mut mesh_instances_queued_this_iteration_scratch_space,
607        ) {
608            // We only want meshes with the marker component to be queued to our phase.
609            if has_marker.get(*render_entity).is_err() {
610                continue;
611            }
612            let Some(mesh_instance) = render_mesh_instances.render_mesh_queue_data(*visible_entity)
613            else {
614                // We couldn't fetch the mesh, probably because it hasn't been
615                // loaded yet. Add the entity to the list of pending custom mesh
616                // queues and bail.
617                view_pending_custom_mesh_queues
618                    .current_frame
619                    .insert((*render_entity, *visible_entity));
620                continue;
621            };
622            let Some(mesh) = render_meshes.get(mesh_instance.mesh_asset_id()) else {
623                continue;
624            };
625
626            // Specialize the key for the current mesh entity
627            // For this example we only specialize based on the mesh topology
628            // but you could have more complex keys and that's where you'd need to create those keys
629            let mut mesh_key = view_key;
630            mesh_key |= MeshPipelineKey::from_primitive_topology_and_strip_index(
631                mesh.primitive_topology(),
632                mesh.index_format(),
633            );
634
635            let pipeline_id = pipelines.specialize(
636                &pipeline_cache,
637                &custom_draw_pipeline,
638                mesh_key,
639                &mesh.layout,
640            );
641            let pipeline_id = match pipeline_id {
642                Ok(id) => id,
643                Err(err) => {
644                    error!("{}", err);
645                    continue;
646                }
647            };
648            // At this point we have all the data we need to create a phase item and add it to our
649            // phase
650            custom_phase.add_retained(Stencil3d {
651                sorting_info: TransparentSortingInfo3d::Sorted {
652                    mesh_center: pbr::get_mesh_instance_world_from_local(
653                        *visible_entity,
654                        mesh_instance.current_uniform_index,
655                        &render_mesh_instances,
656                        maybe_batched_instance_buffers.as_deref(),
657                    )
658                    .transform_point3(
659                        render_meshes
660                            .get(mesh_instance.mesh_asset_id())
661                            .unwrap()
662                            .aabb_center,
663                    ),
664                    depth_bias: 0.0,
665                },
666                distance: FloatOrd(0.0),
667                entity: (Entity::PLACEHOLDER, *visible_entity),
668                pipeline: pipeline_id,
669                draw_function: draw_custom,
670                // Sorted phase items aren't batched
671                batch_range: 0..1,
672                extra_index: PhaseItemExtraIndex::None,
673                indexed: mesh.indexed(),
674            });
675        }
676    }
677}
examples/shader_advanced/specialized_mesh_pipeline.rs (line 362)
312fn queue_custom_mesh_pipeline(
313    pipeline_cache: Res<PipelineCache>,
314    custom_mesh_pipeline: Res<CustomMeshPipeline>,
315    (mut opaque_render_phases, opaque_draw_functions): (
316        ResMut<ViewBinnedRenderPhases<Opaque3d>>,
317        Res<DrawFunctions<Opaque3d>>,
318    ),
319    mut specialized_mesh_pipelines: ResMut<SpecializedMeshPipelines<CustomMeshPipeline>>,
320    views: Query<(&RenderVisibleEntities, &ExtractedView)>,
321    view_key_cache: Res<ViewKeyCache>,
322    (render_meshes, render_mesh_instances): (
323        Res<RenderAssets<RenderMesh>>,
324        Res<RenderMeshInstances>,
325    ),
326    mut change_tick: Local<Tick>,
327    mesh_allocator: Res<MeshAllocator>,
328    gpu_preprocessing_support: Res<GpuPreprocessingSupport>,
329    dirty_specializations: Res<DirtySpecializations>,
330    mut pending_custom_mesh_queues: ResMut<PendingCustomMeshQueues>,
331    mut mesh_instances_queued_this_iteration_scratch_space: Local<MainEntityHashSet>,
332) {
333    // Get the id for our custom draw function
334    let draw_function = opaque_draw_functions
335        .read()
336        .id::<DrawSpecializedPipelineCommands>();
337
338    // Render phases are per-view, so we need to iterate over all views so that
339    // the entity appears in them. (In this example, we have only one view, but
340    // it's good practice to loop over all views anyway.)
341    for (view_visible_entities, view) in views.iter() {
342        let Some(opaque_phase) = opaque_render_phases.get_mut(&view.retained_view_entity) else {
343            continue;
344        };
345
346        let Some(&view_key) = view_key_cache.get(&view.retained_view_entity) else {
347            continue;
348        };
349
350        let Some(render_visible_mesh_entities) =
351            view_visible_entities.get::<CustomRenderedEntity>()
352        else {
353            continue;
354        };
355
356        // Initialize the pending queues.
357        let view_pending_custom_mesh_queues =
358            pending_custom_mesh_queues.prepare_for_new_frame(view.retained_view_entity);
359
360        // First, remove meshes that need to be respecialized, and those that were removed, from the bins.
361        for &main_entity in dirty_specializations
362            .iter_to_dequeue(view.retained_view_entity, render_visible_mesh_entities)
363        {
364            opaque_phase.remove(main_entity);
365        }
366
367        // Find all the custom rendered entities that are visible from this
368        // view.
369        for (render_entity, visible_entity) in dirty_specializations.iter_to_queue(
370            view.retained_view_entity,
371            render_visible_mesh_entities,
372            &view_pending_custom_mesh_queues.prev_frame,
373            &mut mesh_instances_queued_this_iteration_scratch_space,
374        ) {
375            // Get the mesh instance
376            let Some(mesh_instance) = render_mesh_instances.render_mesh_queue_data(*visible_entity)
377            else {
378                // We couldn't fetch the mesh, probably because it hasn't been
379                // loaded yet. Add the entity to the list of pending custom
380                // meshes and bail.
381                view_pending_custom_mesh_queues
382                    .current_frame
383                    .insert((*render_entity, *visible_entity));
384                continue;
385            };
386
387            // Get the mesh data
388            let Some(mesh) = render_meshes.get(mesh_instance.mesh_asset_id()) else {
389                continue;
390            };
391
392            let Some(mesh_slabs) = mesh_allocator.mesh_slabs(&mesh_instance.mesh_asset_id()) else {
393                continue;
394            };
395
396            // Specialize the key for the current mesh entity
397            // For this example we only specialize based on the mesh topology
398            // but you could have more complex keys and that's where you'd need to create those keys
399            let mut mesh_key = view_key;
400            mesh_key |= MeshPipelineKey::from_primitive_topology_and_strip_index(
401                mesh.primitive_topology(),
402                mesh.index_format(),
403            );
404
405            // Finally, we can specialize the pipeline based on the key
406            let pipeline_id = specialized_mesh_pipelines
407                .specialize(
408                    &pipeline_cache,
409                    &custom_mesh_pipeline,
410                    mesh_key,
411                    &mesh.layout,
412                )
413                // This should never happen with this example, but if your pipeline
414                // specialization can fail you need to handle the error here
415                .expect("Failed to specialize mesh pipeline");
416
417            // Bump the change tick so that Bevy is forced to rebuild the bin.
418            let next_change_tick = change_tick.get() + 1;
419            change_tick.set(next_change_tick);
420
421            // Add the mesh with our specialized pipeline
422            opaque_phase.add(
423                Opaque3dBatchSetKey {
424                    draw_function,
425                    pipeline: pipeline_id,
426                    material_bind_group_index: None,
427                    slabs: mesh_slabs,
428                    lightmap_slab: None,
429                },
430                // For this example we can use the mesh asset id as the bin key,
431                // but you can use any asset_id as a key
432                Opaque3dBinKey {
433                    asset_id: mesh_instance.mesh_asset_id().into(),
434                },
435                (*render_entity, *visible_entity),
436                mesh_instance.current_uniform_index,
437                // This example supports batching and multi draw indirect,
438                // but if your pipeline doesn't support it you can use
439                // `BinnedRenderPhaseType::UnbatchableMesh`
440                BinnedRenderPhaseType::mesh(
441                    mesh_instance.should_batch(),
442                    &gpu_preprocessing_support,
443                ),
444            );
445        }
446    }
447}
Source

pub fn iter_to_queue<'a>( &'a self, view: RetainedViewEntity, render_visible_mesh_entities: &'a RenderVisibleEntitiesClass, last_frame_view_pending_queues: &'a HashSet<(Entity, MainEntity)>, mesh_instances_queued_this_iteration_scratch_space: &'a mut EntityEquivalentHashSet<MainEntity>, ) -> impl Iterator<Item = (&'a Entity, &'a MainEntity)>

Iterates over all renderables that potentially need to be re-queued.

This includes both renderables that became visible and those that are in DirtySpecializations::changed_renderables. If this view must itself be re-specialized, this will iterate over all visible renderables.

last_frame_view_pending_queues should be the contents of the ViewPendingQueues::prev_frame list. mesh_instances_queued_this_iteration_scratch_space should be a Local<MainEntityHashSet>; it’s used internally to avoid yielding the same mesh instance multiple times.

Examples found in repository?
examples/shader_advanced/custom_phase_item.rs (lines 273-278)
229fn queue_custom_phase_item(
230    pipeline_cache: Res<PipelineCache>,
231    mut pipeline: ResMut<CustomPhasePipeline>,
232    mut opaque_render_phases: ResMut<ViewBinnedRenderPhases<Opaque3d>>,
233    opaque_draw_functions: Res<DrawFunctions<Opaque3d>>,
234    views: Query<(&ExtractedView, &RenderVisibleEntities, &Msaa)>,
235    dirty_specializations: Res<DirtySpecializations>,
236    mut pending_custom_phase_item_queues: ResMut<PendingCustomPhaseItemQueues>,
237    mut mesh_instances_queued_this_iteration_scratch_space: Local<MainEntityHashSet>,
238) {
239    let draw_custom_phase_item = opaque_draw_functions
240        .read()
241        .id::<DrawCustomPhaseItemCommands>();
242
243    // Render phases are per-view, so we need to iterate over all views so that
244    // the entity appears in them. (In this example, we have only one view, but
245    // it's good practice to loop over all views anyway.)
246    for (view, view_visible_entities, msaa) in views.iter() {
247        let Some(opaque_phase) = opaque_render_phases.get_mut(&view.retained_view_entity) else {
248            continue;
249        };
250
251        // Fetch the list of visible entities in the `CustomRenderedEntity`
252        // class. If there are no such entities, then we have no entities to
253        // render, and we're done.
254        let Some(render_visible_mesh_entities) =
255            view_visible_entities.get::<CustomRenderedEntity>()
256        else {
257            continue;
258        };
259
260        let view_pending_custom_phase_item_queues =
261            pending_custom_phase_item_queues.prepare_for_new_frame(view.retained_view_entity);
262
263        // First, remove meshes that need to be respecialized, and those that
264        // were removed, from the bins.
265        for &main_entity in dirty_specializations
266            .iter_to_dequeue(view.retained_view_entity, render_visible_mesh_entities)
267        {
268            opaque_phase.remove(main_entity);
269        }
270
271        // Find all the custom rendered entities that are visible from this
272        // view.
273        for (render_entity, main_entity) in dirty_specializations.iter_to_queue(
274            view.retained_view_entity,
275            render_visible_mesh_entities,
276            &view_pending_custom_phase_item_queues.prev_frame,
277            &mut mesh_instances_queued_this_iteration_scratch_space,
278        ) {
279            // Ordinarily, the [`SpecializedRenderPipeline::Key`] would contain
280            // some per-view settings, such as whether the view is HDR, but for
281            // simplicity's sake we simply hard-code the view's characteristics,
282            // with the exception of number of MSAA samples.
283            let Ok(pipeline_id) = pipeline
284                .variants
285                .specialize(&pipeline_cache, CustomPhaseKey(*msaa))
286            else {
287                continue;
288            };
289
290            // Add the custom render item. We use the
291            // [`BinnedRenderPhaseType::NonMesh`] type to skip the special
292            // handling that Bevy has for meshes (preprocessing, indirect
293            // draws, etc.)
294            //
295            // The asset ID is arbitrary; we simply use [`AssetId::default`],
296            // but you can use anything you like. Note that the asset ID need
297            // not be the ID of a [`Mesh`].
298            opaque_phase.add(
299                Opaque3dBatchSetKey {
300                    draw_function: draw_custom_phase_item,
301                    pipeline: pipeline_id,
302                    material_bind_group_index: None,
303                    lightmap_slab: None,
304                    slabs: MeshSlabs::default(),
305                },
306                Opaque3dBinKey {
307                    asset_id: AssetId::<Mesh>::default().untyped(),
308                },
309                (*render_entity, *main_entity),
310                InputUniformIndex::default(),
311                BinnedRenderPhaseType::NonMesh,
312            );
313        }
314    }
315}
More examples
Hide additional examples
examples/shader_advanced/custom_render_phase.rs (lines 602-607)
559fn queue_custom_meshes(
560    custom_draw_functions: Res<DrawFunctions<Stencil3d>>,
561    mut pipelines: ResMut<SpecializedMeshPipelines<StencilPipeline>>,
562    pipeline_cache: Res<PipelineCache>,
563    custom_draw_pipeline: Res<StencilPipeline>,
564    render_meshes: Res<RenderAssets<RenderMesh>>,
565    render_mesh_instances: Res<RenderMeshInstances>,
566    maybe_batched_instance_buffers: Option<
567        Res<BatchedInstanceBuffers<MeshUniform, MeshInputUniform>>,
568    >,
569    mut custom_render_phases: ResMut<ViewSortedRenderPhases<Stencil3d>>,
570    mut views: Query<(&ExtractedView, &RenderVisibleEntities)>,
571    view_key_cache: Res<ViewKeyCache>,
572    dirty_specializations: Res<DirtySpecializations>,
573    mut pending_custom_mesh_queues: ResMut<PendingCustomMeshQueues>,
574    has_marker: Query<(), With<DrawStencil>>,
575    mut mesh_instances_queued_this_iteration_scratch_space: Local<MainEntityHashSet>,
576) {
577    for (view, visible_entities) in &mut views {
578        let Some(custom_phase) = custom_render_phases.get_mut(&view.retained_view_entity) else {
579            continue;
580        };
581        let draw_custom = custom_draw_functions.read().id::<DrawMesh3dStencil>();
582
583        let Some(&view_key) = view_key_cache.get(&view.retained_view_entity) else {
584            continue;
585        };
586
587        // Since our phase can work on any 3d mesh we can reuse the default mesh 3d filter
588        let Some(render_visible_mesh_entities) = visible_entities.get::<Mesh3d>() else {
589            continue;
590        };
591
592        let view_pending_custom_mesh_queues =
593            pending_custom_mesh_queues.prepare_for_new_frame(view.retained_view_entity);
594
595        // First, remove meshes that need to be respecialized, and those that were removed, from the bins.
596        for &main_entity in dirty_specializations
597            .iter_to_dequeue(view.retained_view_entity, render_visible_mesh_entities)
598        {
599            custom_phase.remove(Entity::PLACEHOLDER, main_entity);
600        }
601
602        for (render_entity, visible_entity) in dirty_specializations.iter_to_queue(
603            view.retained_view_entity,
604            render_visible_mesh_entities,
605            &view_pending_custom_mesh_queues.prev_frame,
606            &mut mesh_instances_queued_this_iteration_scratch_space,
607        ) {
608            // We only want meshes with the marker component to be queued to our phase.
609            if has_marker.get(*render_entity).is_err() {
610                continue;
611            }
612            let Some(mesh_instance) = render_mesh_instances.render_mesh_queue_data(*visible_entity)
613            else {
614                // We couldn't fetch the mesh, probably because it hasn't been
615                // loaded yet. Add the entity to the list of pending custom mesh
616                // queues and bail.
617                view_pending_custom_mesh_queues
618                    .current_frame
619                    .insert((*render_entity, *visible_entity));
620                continue;
621            };
622            let Some(mesh) = render_meshes.get(mesh_instance.mesh_asset_id()) else {
623                continue;
624            };
625
626            // Specialize the key for the current mesh entity
627            // For this example we only specialize based on the mesh topology
628            // but you could have more complex keys and that's where you'd need to create those keys
629            let mut mesh_key = view_key;
630            mesh_key |= MeshPipelineKey::from_primitive_topology_and_strip_index(
631                mesh.primitive_topology(),
632                mesh.index_format(),
633            );
634
635            let pipeline_id = pipelines.specialize(
636                &pipeline_cache,
637                &custom_draw_pipeline,
638                mesh_key,
639                &mesh.layout,
640            );
641            let pipeline_id = match pipeline_id {
642                Ok(id) => id,
643                Err(err) => {
644                    error!("{}", err);
645                    continue;
646                }
647            };
648            // At this point we have all the data we need to create a phase item and add it to our
649            // phase
650            custom_phase.add_retained(Stencil3d {
651                sorting_info: TransparentSortingInfo3d::Sorted {
652                    mesh_center: pbr::get_mesh_instance_world_from_local(
653                        *visible_entity,
654                        mesh_instance.current_uniform_index,
655                        &render_mesh_instances,
656                        maybe_batched_instance_buffers.as_deref(),
657                    )
658                    .transform_point3(
659                        render_meshes
660                            .get(mesh_instance.mesh_asset_id())
661                            .unwrap()
662                            .aabb_center,
663                    ),
664                    depth_bias: 0.0,
665                },
666                distance: FloatOrd(0.0),
667                entity: (Entity::PLACEHOLDER, *visible_entity),
668                pipeline: pipeline_id,
669                draw_function: draw_custom,
670                // Sorted phase items aren't batched
671                batch_range: 0..1,
672                extra_index: PhaseItemExtraIndex::None,
673                indexed: mesh.indexed(),
674            });
675        }
676    }
677}
examples/shader_advanced/specialized_mesh_pipeline.rs (lines 369-374)
312fn queue_custom_mesh_pipeline(
313    pipeline_cache: Res<PipelineCache>,
314    custom_mesh_pipeline: Res<CustomMeshPipeline>,
315    (mut opaque_render_phases, opaque_draw_functions): (
316        ResMut<ViewBinnedRenderPhases<Opaque3d>>,
317        Res<DrawFunctions<Opaque3d>>,
318    ),
319    mut specialized_mesh_pipelines: ResMut<SpecializedMeshPipelines<CustomMeshPipeline>>,
320    views: Query<(&RenderVisibleEntities, &ExtractedView)>,
321    view_key_cache: Res<ViewKeyCache>,
322    (render_meshes, render_mesh_instances): (
323        Res<RenderAssets<RenderMesh>>,
324        Res<RenderMeshInstances>,
325    ),
326    mut change_tick: Local<Tick>,
327    mesh_allocator: Res<MeshAllocator>,
328    gpu_preprocessing_support: Res<GpuPreprocessingSupport>,
329    dirty_specializations: Res<DirtySpecializations>,
330    mut pending_custom_mesh_queues: ResMut<PendingCustomMeshQueues>,
331    mut mesh_instances_queued_this_iteration_scratch_space: Local<MainEntityHashSet>,
332) {
333    // Get the id for our custom draw function
334    let draw_function = opaque_draw_functions
335        .read()
336        .id::<DrawSpecializedPipelineCommands>();
337
338    // Render phases are per-view, so we need to iterate over all views so that
339    // the entity appears in them. (In this example, we have only one view, but
340    // it's good practice to loop over all views anyway.)
341    for (view_visible_entities, view) in views.iter() {
342        let Some(opaque_phase) = opaque_render_phases.get_mut(&view.retained_view_entity) else {
343            continue;
344        };
345
346        let Some(&view_key) = view_key_cache.get(&view.retained_view_entity) else {
347            continue;
348        };
349
350        let Some(render_visible_mesh_entities) =
351            view_visible_entities.get::<CustomRenderedEntity>()
352        else {
353            continue;
354        };
355
356        // Initialize the pending queues.
357        let view_pending_custom_mesh_queues =
358            pending_custom_mesh_queues.prepare_for_new_frame(view.retained_view_entity);
359
360        // First, remove meshes that need to be respecialized, and those that were removed, from the bins.
361        for &main_entity in dirty_specializations
362            .iter_to_dequeue(view.retained_view_entity, render_visible_mesh_entities)
363        {
364            opaque_phase.remove(main_entity);
365        }
366
367        // Find all the custom rendered entities that are visible from this
368        // view.
369        for (render_entity, visible_entity) in dirty_specializations.iter_to_queue(
370            view.retained_view_entity,
371            render_visible_mesh_entities,
372            &view_pending_custom_mesh_queues.prev_frame,
373            &mut mesh_instances_queued_this_iteration_scratch_space,
374        ) {
375            // Get the mesh instance
376            let Some(mesh_instance) = render_mesh_instances.render_mesh_queue_data(*visible_entity)
377            else {
378                // We couldn't fetch the mesh, probably because it hasn't been
379                // loaded yet. Add the entity to the list of pending custom
380                // meshes and bail.
381                view_pending_custom_mesh_queues
382                    .current_frame
383                    .insert((*render_entity, *visible_entity));
384                continue;
385            };
386
387            // Get the mesh data
388            let Some(mesh) = render_meshes.get(mesh_instance.mesh_asset_id()) else {
389                continue;
390            };
391
392            let Some(mesh_slabs) = mesh_allocator.mesh_slabs(&mesh_instance.mesh_asset_id()) else {
393                continue;
394            };
395
396            // Specialize the key for the current mesh entity
397            // For this example we only specialize based on the mesh topology
398            // but you could have more complex keys and that's where you'd need to create those keys
399            let mut mesh_key = view_key;
400            mesh_key |= MeshPipelineKey::from_primitive_topology_and_strip_index(
401                mesh.primitive_topology(),
402                mesh.index_format(),
403            );
404
405            // Finally, we can specialize the pipeline based on the key
406            let pipeline_id = specialized_mesh_pipelines
407                .specialize(
408                    &pipeline_cache,
409                    &custom_mesh_pipeline,
410                    mesh_key,
411                    &mesh.layout,
412                )
413                // This should never happen with this example, but if your pipeline
414                // specialization can fail you need to handle the error here
415                .expect("Failed to specialize mesh pipeline");
416
417            // Bump the change tick so that Bevy is forced to rebuild the bin.
418            let next_change_tick = change_tick.get() + 1;
419            change_tick.set(next_change_tick);
420
421            // Add the mesh with our specialized pipeline
422            opaque_phase.add(
423                Opaque3dBatchSetKey {
424                    draw_function,
425                    pipeline: pipeline_id,
426                    material_bind_group_index: None,
427                    slabs: mesh_slabs,
428                    lightmap_slab: None,
429                },
430                // For this example we can use the mesh asset id as the bin key,
431                // but you can use any asset_id as a key
432                Opaque3dBinKey {
433                    asset_id: mesh_instance.mesh_asset_id().into(),
434                },
435                (*render_entity, *visible_entity),
436                mesh_instance.current_uniform_index,
437                // This example supports batching and multi draw indirect,
438                // but if your pipeline doesn't support it you can use
439                // `BinnedRenderPhaseType::UnbatchableMesh`
440                BinnedRenderPhaseType::mesh(
441                    mesh_instance.should_batch(),
442                    &gpu_preprocessing_support,
443                ),
444            );
445        }
446    }
447}

Trait Implementations§

Source§

impl Clone for DirtyWireframeSpecializations

Source§

fn clone(&self) -> DirtyWireframeSpecializations

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Component for DirtyWireframeSpecializations

Source§

const STORAGE_TYPE: StorageType = bevy_ecs::component::StorageType::SparseSet

A constant indicating the storage type used for this component.
Source§

type Mutability = Mutable

A marker type to assist Bevy with determining if this component is mutable, or immutable. Mutable components will have Component<Mutability = Mutable>, while immutable components will instead have Component<Mutability = Immutable>. Read more
Source§

fn register_required_components( _requiree: ComponentId, required_components: &mut RequiredComponentsRegistrator<'_, '_>, )

Registers required components. Read more
Source§

fn clone_behavior() -> ComponentCloneBehavior

Called when registering this component, allowing to override clone function (or disable cloning altogether) for this component. Read more
Source§

fn relationship_accessor() -> Option<ComponentRelationshipAccessor<DirtyWireframeSpecializations>>

Returns ComponentRelationshipAccessor required for working with relationships in dynamic contexts. Read more
Source§

fn on_add() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_add ComponentHook for this Component if one is defined.
Source§

fn on_insert() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_insert ComponentHook for this Component if one is defined.
Source§

fn on_discard() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_discard ComponentHook for this Component if one is defined.
Source§

fn on_remove() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_remove ComponentHook for this Component if one is defined.
Source§

fn on_despawn() -> Option<for<'w> fn(DeferredWorld<'w>, HookContext)>

Gets the on_despawn ComponentHook for this Component if one is defined.
Source§

fn map_entities<E>(_this: &mut Self, _mapper: &mut E)
where E: EntityMapper,

Maps the entities on this component using the given EntityMapper. This is used to remap entities in contexts like scenes and entity cloning. When deriving Component, this is populated by annotating fields containing entities with #[entities] Read more
Source§

const HAS_SUMMARY_TICK: bool = false

Set this constant to true if the component should track a summary tick. Read more
Source§

impl Default for DirtyWireframeSpecializations

Source§

fn default() -> DirtyWireframeSpecializations

Returns the “default value” for a type. Read more
Source§

impl Deref for DirtyWireframeSpecializations

Source§

type Target = DirtySpecializations

The resulting type after dereferencing.
Source§

fn deref(&self) -> &<DirtyWireframeSpecializations as Deref>::Target

Dereferences the value.
Source§

impl DerefMut for DirtyWireframeSpecializations

Source§

fn deref_mut(&mut self) -> &mut <DirtyWireframeSpecializations as Deref>::Target

Mutably dereferences the value.
Source§

impl Resource for DirtyWireframeSpecializations

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T, U> AsBindGroupShaderType<U> for T
where U: ShaderType, &'a T: for<'a> Into<U>,

Source§

fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U

Return the T ShaderType for self. When used in AsBindGroup derives, it is safe to assume that all images in self exist.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<C> Bundle for C
where C: Component,

Source§

fn component_ids( components: &mut ComponentsRegistrator<'_>, ) -> impl Iterator<Item = ComponentId> + use<C>

Source§

fn get_component_ids( components: &Components, ) -> impl Iterator<Item = Option<ComponentId>>

Returns an iterator over this Bundle’s component ids. This will be None if the component has not been registered.
Source§

impl<C> BundleFromComponents for C
where C: Component,

Source§

unsafe fn from_components<T, F>(ctx: &mut T, func: &mut F) -> C
where F: for<'a> FnMut(&'a mut T) -> OwningPtr<'a>, C: Sized,

Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> ConditionalSend for T
where T: Send,

Source§

impl<T> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send> ⓘ

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<C> DynamicBundle for C
where C: Component,

Source§

type Effect = ()

An operation on the entity that happens after inserting this bundle.
Source§

unsafe fn get_components( ptr: MovingPtr<'_, C>, func: &mut impl FnMut(StorageType, OwningPtr<'_>), ) -> <C as DynamicBundle>::Effect

Moves the components out of the bundle. Read more
Source§

unsafe fn apply_effect( _ptr: MovingPtr<'_, MaybeUninit<C>>, _entity: &mut EntityWorldMut<'_>, )

Applies the after-effects of spawning this bundle. Read more
Source§

impl<T> ErasedBundleTemplate for T
where T: Template + Send + Sync + 'static, <T as Template>::Output: Bundle,

Source§

unsafe fn apply( &self, context: &mut TemplateContext<'_, '_>, ) -> Result<(), BevyError>

Applies this template to the given entity. Read more
Source§

fn clone_template(&self) -> Box<dyn ErasedBundleTemplate>

Clones this template. See Clone.
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> ErasedTemplate for T
where T: Template + Send + Sync + 'static, <T as Template>::Output: SceneEffect,

Source§

unsafe fn apply( &self, context: &mut TemplateContext<'_, '_>, bundle_writer: &mut BundleWriter<'_>, ) -> Result<(), BevyError>

Applies this template to the given entity. Read more
Source§

fn clone_template(&self) -> Box<dyn ErasedTemplate>

Clones this template. See Clone.
Source§

impl<T> FmtForward for T

Source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
Source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
Source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
Source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
Source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
Source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
Source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
Source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
Source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T> FromTemplate for T
where T: Clone + Default + Unpin,

Source§

type Template = T

The Template for this type.
Source§

impl<T> FromWorld for T
where T: Default,

Source§

fn from_world(_world: &mut World) -> T

Creates Self using default().

Source§

impl<T, W> HasTypeWitness<W> for T
where W: MakeTypeWitness<Arg = T>, T: ?Sized,

Source§

const WITNESS: W = W::MAKE

A constant of the type witness
Source§

impl<T> Identity for T
where T: ?Sized,

Source§

const TYPE_EQ: TypeEq<T, <T as Identity>::Type> = TypeEq::NEW

Proof that Self is the same type as Self::Type, provides methods for casting between Self and Self::Type.
Source§

type Type = T

The same type as Self, used to emulate type equality bounds (T == U) with associated type equality constraints (T: Identity<Type = U>).
Source§

impl<T> InitializeFromFunction<T> for T

Source§

fn initialize_from_function(f: fn() -> T) -> T

Create an instance of this type from an initialization function
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> IntoResult<T> for T

Source§

fn into_result(self) -> Result<T, RunSystemError>

Converts this type into the system output type.
Source§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

impl<A> Is for A
where A: Any,

Source§

fn is<T>() -> bool
where T: Any,

Checks if the current type “is” another type, using a TypeId equality comparison. This is most useful in the context of generic logic. Read more
Source§

impl<T> NoneValue for T
where T: Default,

Source§

type NoneType = T

Source§

fn null_value() -> T

The none-equivalent value.
Source§

impl<G> PatchFromTemplate for G
where G: FromTemplate,

Source§

type Template = <G as FromTemplate>::Template

The Template that will be patched.
Source§

fn patch<F>(func: F) -> TemplatePatch<F, <G as PatchFromTemplate>::Template>
where F: FnOnce(&mut <G as PatchFromTemplate>::Template, &mut ResolveContext<'_>),

Takes a “patch function” func, and turns it into a TemplatePatch.
Source§

impl<T> PatchTemplate for T
where T: Template,

Source§

fn patch_template<F>(func: F) -> TemplatePatch<F, T>
where F: FnOnce(&mut T, &mut ResolveContext<'_>),

Takes a “patch function” func that patches this Template, and turns it into a TemplatePatch.
Source§

impl<T> Pipe for T
where T: ?Sized,

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
Source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
Source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<R, P> ReadPrimitive<R> for P
where R: Read + ReadEndian<P>, P: Default,

Source§

fn read_from_little_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_little_endian().
Source§

fn read_from_big_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_big_endian().
Source§

fn read_from_native_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_native_endian().
Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<C> SceneEffect for C
where C: Component,

Source§

fn apply( self, context: &mut TemplateContext<'_, '_>, bundle_writer: &mut BundleWriter<'_>, )

Applies the scene effect to the current context.
Source§

impl<T> Settings for T
where T: 'static + Send + Sync,

Source§

impl<Ret> SpawnIfAsync<(), Ret> for Ret

Source§

fn spawn(self) -> Ret

Spawn the value into the dioxus runtime if it is an async block
Source§

impl<T, O> SuperFrom<T> for O
where O: From<T>,

Source§

fn super_from(input: T) -> O

Convert from a type to another type.
Source§

impl<T, O, M> SuperInto<O, M> for T
where O: SuperFrom<T, M>,

Source§

fn super_into(self) -> O

Convert from a type to another type.
Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> Template for T
where T: Clone + Unpin,

Source§

type Output = T

The type of value produced by this Template.
Source§

fn build_template( &self, _context: &mut TemplateContext<'_, '_>, ) -> Result<<T as Template>::Output, BevyError>

Uses this template and the given entity context to produce a Template::Output.
Source§

fn clone_template(&self) -> T

Clones this template. See Clone.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> TypeData for T
where T: 'static + Send + Sync + Clone,

Source§

fn clone_type_data(&self) -> Box<dyn TypeData>

Creates a type-erased clone of self.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more