wde_renderer/passes/
pipeline_register_plugin.rs

1use bevy::prelude::*;
2
3use crate::{
4    assets::{RenderAsset, RenderAssetsPlugin},
5    core::RenderApp
6};
7
8/// Describes a render pipeline asset (used by [`RenderPipelinePluginRegister`]) which will be responsible of storing the render pipeline instance.
9/// Most of the time, you will use it as a type alias for the `SourceAsset` of your render pipeline.
10/// The render pipeline should derive the [`RenderAsset`], [`TypePath`], [`Default`], [`Clone`] and [`Debug`] traits, and implement the `prepare` function to create the render pipeline instance from the asset data.
11/// See [crate::passes] for more details and examples.
12#[derive(Default, Asset, Clone, TypePath, Debug)]
13pub struct RenderPipelineAsset<P: RenderAsset + TypePath>(pub P);
14impl<P: RenderAsset + TypePath> std::fmt::Display for RenderPipelineAsset<P> {
15    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16        write!(f, "RenderPipelineAsset<{}>", std::any::type_name::<P>())
17    }
18}
19
20/// Component to hold a render pipeline asset handle, preventing it from being dropped and unloaded.
21#[allow(unused)]
22#[derive(Component)]
23struct RenderPipelineAssetHolder<P: RenderAsset + TypePath>(pub Handle<RenderPipelineAsset<P>>);
24
25/// A plugin for registering a render pipeline asset and its preparation logic.
26/// It will also spawn an entity holding the render pipeline asset handle, preventing it from being dropped and unloaded.
27///
28/// To use it, simply add it to your app with the render pipeline asset type as generic parameter:
29/// ```rust
30/// app.add_plugins(RenderPipelinePluginRegister::<MyRenderPipelineAsset>::default());
31/// ```
32/// The render pipeline should derive the [`RenderAsset`], [`TypePath`], [`Default`] and [`Clone`] traits.
33/// It should use the [`RenderPipelineAsset`] as its `SourceAsset` type.
34///
35/// See [crate::passes] for more details and examples.
36pub struct RenderPipelineRegisterPlugin<P: RenderAsset + TypePath + Default> {
37    _phantom: std::marker::PhantomData<P>
38}
39impl<P: RenderAsset + TypePath + Default> Default for RenderPipelineRegisterPlugin<P> {
40    fn default() -> Self {
41        Self {
42            _phantom: std::marker::PhantomData
43        }
44    }
45}
46impl<P: RenderAsset + TypePath + Default> Plugin for RenderPipelineRegisterPlugin<P> {
47    fn build(&self, app: &mut App) {
48        // Add the render pipeline asset and its preparation plugin
49        app.init_asset::<RenderPipelineAsset<P>>()
50            .add_plugins(RenderAssetsPlugin::<P>::default());
51    }
52
53    fn finish(&self, app: &mut App) {
54        // Create the render pipeline asset
55        let pipeline = app
56            .world_mut()
57            .get_resource::<AssetServer>()
58            .unwrap()
59            .add(RenderPipelineAsset::<P>::default());
60
61        // Spawn an entity holding the render pipeline asset handle, avoiding it to be dropped and unloaded
62        app.get_sub_app_mut(RenderApp)
63            .unwrap()
64            .world_mut()
65            .spawn(RenderPipelineAssetHolder(pipeline));
66    }
67}