bevy_render/render_graph/
app.rs

1use bevy_app::{App, SubApp};
2use bevy_ecs::world::{FromWorld, World};
3use tracing::warn;
4
5use super::{IntoRenderNodeArray, Node, RenderGraph, RenderLabel, RenderSubGraph};
6
7/// Adds common [`RenderGraph`] operations to [`SubApp`] (and [`App`]).
8pub trait RenderGraphExt {
9    // Add a sub graph to the [`RenderGraph`]
10    fn add_render_sub_graph(&mut self, sub_graph: impl RenderSubGraph) -> &mut Self;
11    /// Add a [`Node`] to the [`RenderGraph`]:
12    /// * Create the [`Node`] using the [`FromWorld`] implementation
13    /// * Add it to the graph
14    fn add_render_graph_node<T: Node + FromWorld>(
15        &mut self,
16        sub_graph: impl RenderSubGraph,
17        node_label: impl RenderLabel,
18    ) -> &mut Self;
19    /// Automatically add the required node edges based on the given ordering
20    fn add_render_graph_edges<const N: usize>(
21        &mut self,
22        sub_graph: impl RenderSubGraph,
23        edges: impl IntoRenderNodeArray<N>,
24    ) -> &mut Self;
25
26    /// Add node edge to the specified graph
27    fn add_render_graph_edge(
28        &mut self,
29        sub_graph: impl RenderSubGraph,
30        output_node: impl RenderLabel,
31        input_node: impl RenderLabel,
32    ) -> &mut Self;
33}
34
35impl RenderGraphExt for World {
36    fn add_render_graph_node<T: Node + FromWorld>(
37        &mut self,
38        sub_graph: impl RenderSubGraph,
39        node_label: impl RenderLabel,
40    ) -> &mut Self {
41        let sub_graph = sub_graph.intern();
42        let node = T::from_world(self);
43        let mut render_graph = self.get_resource_mut::<RenderGraph>().expect(
44            "RenderGraph not found. Make sure you are using add_render_graph_node on the RenderApp",
45        );
46        if let Some(graph) = render_graph.get_sub_graph_mut(sub_graph) {
47            graph.add_node(node_label, node);
48        } else {
49            warn!(
50                "Tried adding a render graph node to {sub_graph:?} but the sub graph doesn't exist"
51            );
52        }
53        self
54    }
55
56    #[track_caller]
57    fn add_render_graph_edges<const N: usize>(
58        &mut self,
59        sub_graph: impl RenderSubGraph,
60        edges: impl IntoRenderNodeArray<N>,
61    ) -> &mut Self {
62        let sub_graph = sub_graph.intern();
63        let mut render_graph = self.get_resource_mut::<RenderGraph>().expect(
64            "RenderGraph not found. Make sure you are using add_render_graph_edges on the RenderApp",
65        );
66        if let Some(graph) = render_graph.get_sub_graph_mut(sub_graph) {
67            graph.add_node_edges(edges);
68        } else {
69            warn!(
70                "Tried adding render graph edges to {sub_graph:?} but the sub graph doesn't exist"
71            );
72        }
73        self
74    }
75
76    fn add_render_graph_edge(
77        &mut self,
78        sub_graph: impl RenderSubGraph,
79        output_node: impl RenderLabel,
80        input_node: impl RenderLabel,
81    ) -> &mut Self {
82        let sub_graph = sub_graph.intern();
83        let mut render_graph = self.get_resource_mut::<RenderGraph>().expect(
84            "RenderGraph not found. Make sure you are using add_render_graph_edge on the RenderApp",
85        );
86        if let Some(graph) = render_graph.get_sub_graph_mut(sub_graph) {
87            graph.add_node_edge(output_node, input_node);
88        } else {
89            warn!(
90                "Tried adding a render graph edge to {sub_graph:?} but the sub graph doesn't exist"
91            );
92        }
93        self
94    }
95
96    fn add_render_sub_graph(&mut self, sub_graph: impl RenderSubGraph) -> &mut Self {
97        let mut render_graph = self.get_resource_mut::<RenderGraph>().expect(
98            "RenderGraph not found. Make sure you are using add_render_sub_graph on the RenderApp",
99        );
100        render_graph.add_sub_graph(sub_graph, RenderGraph::default());
101        self
102    }
103}
104
105impl RenderGraphExt for SubApp {
106    fn add_render_graph_node<T: Node + FromWorld>(
107        &mut self,
108        sub_graph: impl RenderSubGraph,
109        node_label: impl RenderLabel,
110    ) -> &mut Self {
111        World::add_render_graph_node::<T>(self.world_mut(), sub_graph, node_label);
112        self
113    }
114
115    fn add_render_graph_edge(
116        &mut self,
117        sub_graph: impl RenderSubGraph,
118        output_node: impl RenderLabel,
119        input_node: impl RenderLabel,
120    ) -> &mut Self {
121        World::add_render_graph_edge(self.world_mut(), sub_graph, output_node, input_node);
122        self
123    }
124
125    #[track_caller]
126    fn add_render_graph_edges<const N: usize>(
127        &mut self,
128        sub_graph: impl RenderSubGraph,
129        edges: impl IntoRenderNodeArray<N>,
130    ) -> &mut Self {
131        World::add_render_graph_edges(self.world_mut(), sub_graph, edges);
132        self
133    }
134
135    fn add_render_sub_graph(&mut self, sub_graph: impl RenderSubGraph) -> &mut Self {
136        World::add_render_sub_graph(self.world_mut(), sub_graph);
137        self
138    }
139}
140
141impl RenderGraphExt for App {
142    fn add_render_graph_node<T: Node + FromWorld>(
143        &mut self,
144        sub_graph: impl RenderSubGraph,
145        node_label: impl RenderLabel,
146    ) -> &mut Self {
147        World::add_render_graph_node::<T>(self.world_mut(), sub_graph, node_label);
148        self
149    }
150
151    fn add_render_graph_edge(
152        &mut self,
153        sub_graph: impl RenderSubGraph,
154        output_node: impl RenderLabel,
155        input_node: impl RenderLabel,
156    ) -> &mut Self {
157        World::add_render_graph_edge(self.world_mut(), sub_graph, output_node, input_node);
158        self
159    }
160
161    fn add_render_graph_edges<const N: usize>(
162        &mut self,
163        sub_graph: impl RenderSubGraph,
164        edges: impl IntoRenderNodeArray<N>,
165    ) -> &mut Self {
166        World::add_render_graph_edges(self.world_mut(), sub_graph, edges);
167        self
168    }
169
170    fn add_render_sub_graph(&mut self, sub_graph: impl RenderSubGraph) -> &mut Self {
171        World::add_render_sub_graph(self.world_mut(), sub_graph);
172        self
173    }
174}