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}