@@ -9,6 +9,8 @@ use bevy_ecs::prelude::World;
9
9
use bevy_utils:: HashMap ;
10
10
use std:: { borrow:: Cow , fmt:: Debug } ;
11
11
12
+ use super :: EdgeExistence ;
13
+
12
14
/// The render graph configures the modular, parallel and re-usable render logic.
13
15
/// It is a retained and stateless (nodes itself my have their internal state) structure,
14
16
/// which can not be modified while it is executed by the graph runner.
@@ -99,6 +101,69 @@ impl RenderGraph {
99
101
id
100
102
}
101
103
104
+ /// Removes the `node` with the `name` from the graph.
105
+ /// If the name is does not exist, nothing happens.
106
+ pub fn remove_node (
107
+ & mut self ,
108
+ name : impl Into < Cow < ' static , str > > ,
109
+ ) -> Result < ( ) , RenderGraphError > {
110
+ let name = name. into ( ) ;
111
+ if let Some ( id) = self . node_names . remove ( & name) {
112
+ if let Some ( node_state) = self . nodes . remove ( & id) {
113
+ // Remove all edges from other nodes to this one. Note that as we're removing this
114
+ // node, we don't need to remove its input edges
115
+ for input_edge in node_state. edges . input_edges ( ) . iter ( ) {
116
+ match input_edge {
117
+ Edge :: SlotEdge {
118
+ output_node,
119
+ output_index : _,
120
+ input_node : _,
121
+ input_index : _,
122
+ } => {
123
+ if let Ok ( output_node) = self . get_node_state_mut ( * output_node) {
124
+ output_node. edges . remove_output_edge ( input_edge. clone ( ) ) ?;
125
+ }
126
+ }
127
+ Edge :: NodeEdge {
128
+ input_node : _,
129
+ output_node,
130
+ } => {
131
+ if let Ok ( output_node) = self . get_node_state_mut ( * output_node) {
132
+ output_node. edges . remove_output_edge ( input_edge. clone ( ) ) ?;
133
+ }
134
+ }
135
+ }
136
+ }
137
+ // Remove all edges from this node to other nodes. Note that as we're removing this
138
+ // node, we don't need to remove its output edges
139
+ for output_edge in node_state. edges . output_edges ( ) . iter ( ) {
140
+ match output_edge {
141
+ Edge :: SlotEdge {
142
+ output_node : _,
143
+ output_index : _,
144
+ input_node,
145
+ input_index : _,
146
+ } => {
147
+ if let Ok ( input_node) = self . get_node_state_mut ( * input_node) {
148
+ input_node. edges . remove_input_edge ( output_edge. clone ( ) ) ?;
149
+ }
150
+ }
151
+ Edge :: NodeEdge {
152
+ output_node : _,
153
+ input_node,
154
+ } => {
155
+ if let Ok ( input_node) = self . get_node_state_mut ( * input_node) {
156
+ input_node. edges . remove_input_edge ( output_edge. clone ( ) ) ?;
157
+ }
158
+ }
159
+ }
160
+ }
161
+ }
162
+ }
163
+
164
+ Ok ( ( ) )
165
+ }
166
+
102
167
/// Retrieves the [`NodeState`] referenced by the `label`.
103
168
pub fn get_node_state (
104
169
& self ,
@@ -187,7 +252,7 @@ impl RenderGraph {
187
252
input_index,
188
253
} ;
189
254
190
- self . validate_edge ( & edge) ?;
255
+ self . validate_edge ( & edge, EdgeExistence :: DoesNotExist ) ?;
191
256
192
257
{
193
258
let output_node = self . get_node_state_mut ( output_node_id) ?;
@@ -199,6 +264,50 @@ impl RenderGraph {
199
264
Ok ( ( ) )
200
265
}
201
266
267
+ /// Removes the [`Edge::SlotEdge`] from the graph. If any nodes or slots do not exist then
268
+ /// nothing happens.
269
+ pub fn remove_slot_edge (
270
+ & mut self ,
271
+ output_node : impl Into < NodeLabel > ,
272
+ output_slot : impl Into < SlotLabel > ,
273
+ input_node : impl Into < NodeLabel > ,
274
+ input_slot : impl Into < SlotLabel > ,
275
+ ) -> Result < ( ) , RenderGraphError > {
276
+ let output_slot = output_slot. into ( ) ;
277
+ let input_slot = input_slot. into ( ) ;
278
+ let output_node_id = self . get_node_id ( output_node) ?;
279
+ let input_node_id = self . get_node_id ( input_node) ?;
280
+
281
+ let output_index = self
282
+ . get_node_state ( output_node_id) ?
283
+ . output_slots
284
+ . get_slot_index ( output_slot. clone ( ) )
285
+ . ok_or ( RenderGraphError :: InvalidOutputNodeSlot ( output_slot) ) ?;
286
+ let input_index = self
287
+ . get_node_state ( input_node_id) ?
288
+ . input_slots
289
+ . get_slot_index ( input_slot. clone ( ) )
290
+ . ok_or ( RenderGraphError :: InvalidInputNodeSlot ( input_slot) ) ?;
291
+
292
+ let edge = Edge :: SlotEdge {
293
+ output_node : output_node_id,
294
+ output_index,
295
+ input_node : input_node_id,
296
+ input_index,
297
+ } ;
298
+
299
+ self . validate_edge ( & edge, EdgeExistence :: Exists ) ?;
300
+
301
+ {
302
+ let output_node = self . get_node_state_mut ( output_node_id) ?;
303
+ output_node. edges . remove_output_edge ( edge. clone ( ) ) ?;
304
+ }
305
+ let input_node = self . get_node_state_mut ( input_node_id) ?;
306
+ input_node. edges . remove_input_edge ( edge) ?;
307
+
308
+ Ok ( ( ) )
309
+ }
310
+
202
311
/// Adds the [`Edge::NodeEdge`] to the graph. This guarantees that the `output_node`
203
312
/// is run before the `input_node`.
204
313
pub fn add_node_edge (
@@ -214,7 +323,7 @@ impl RenderGraph {
214
323
input_node : input_node_id,
215
324
} ;
216
325
217
- self . validate_edge ( & edge) ?;
326
+ self . validate_edge ( & edge, EdgeExistence :: DoesNotExist ) ?;
218
327
219
328
{
220
329
let output_node = self . get_node_state_mut ( output_node_id) ?;
@@ -226,10 +335,43 @@ impl RenderGraph {
226
335
Ok ( ( ) )
227
336
}
228
337
229
- /// Verifies that the edge is not already existing and
338
+ /// Removes the [`Edge::NodeEdge`] from the graph. If either node does not exist then nothing
339
+ /// happens.
340
+ pub fn remove_node_edge (
341
+ & mut self ,
342
+ output_node : impl Into < NodeLabel > ,
343
+ input_node : impl Into < NodeLabel > ,
344
+ ) -> Result < ( ) , RenderGraphError > {
345
+ let output_node_id = self . get_node_id ( output_node) ?;
346
+ let input_node_id = self . get_node_id ( input_node) ?;
347
+
348
+ let edge = Edge :: NodeEdge {
349
+ output_node : output_node_id,
350
+ input_node : input_node_id,
351
+ } ;
352
+
353
+ self . validate_edge ( & edge, EdgeExistence :: Exists ) ?;
354
+
355
+ {
356
+ let output_node = self . get_node_state_mut ( output_node_id) ?;
357
+ output_node. edges . remove_output_edge ( edge. clone ( ) ) ?;
358
+ }
359
+ let input_node = self . get_node_state_mut ( input_node_id) ?;
360
+ input_node. edges . remove_input_edge ( edge) ?;
361
+
362
+ Ok ( ( ) )
363
+ }
364
+
365
+ /// Verifies that the edge existence is as expected and
230
366
/// checks that slot edges are connected correctly.
231
- pub fn validate_edge ( & mut self , edge : & Edge ) -> Result < ( ) , RenderGraphError > {
232
- if self . has_edge ( edge) {
367
+ pub fn validate_edge (
368
+ & mut self ,
369
+ edge : & Edge ,
370
+ should_exist : EdgeExistence ,
371
+ ) -> Result < ( ) , RenderGraphError > {
372
+ if should_exist == EdgeExistence :: Exists && !self . has_edge ( edge) {
373
+ return Err ( RenderGraphError :: EdgeDoesNotExist ( edge. clone ( ) ) ) ;
374
+ } else if should_exist == EdgeExistence :: DoesNotExist && self . has_edge ( edge) {
233
375
return Err ( RenderGraphError :: EdgeAlreadyExists ( edge. clone ( ) ) ) ;
234
376
}
235
377
@@ -256,7 +398,7 @@ impl RenderGraph {
256
398
if let Some ( Edge :: SlotEdge {
257
399
output_node : current_output_node,
258
400
..
259
- } ) = input_node_state. edges . input_edges . iter ( ) . find ( |e| {
401
+ } ) = input_node_state. edges . input_edges ( ) . iter ( ) . find ( |e| {
260
402
if let Edge :: SlotEdge {
261
403
input_index : current_input_index,
262
404
..
@@ -267,11 +409,13 @@ impl RenderGraph {
267
409
false
268
410
}
269
411
} ) {
270
- return Err ( RenderGraphError :: NodeInputSlotAlreadyOccupied {
271
- node : input_node,
272
- input_slot : input_index,
273
- occupied_by_node : * current_output_node,
274
- } ) ;
412
+ if should_exist == EdgeExistence :: DoesNotExist {
413
+ return Err ( RenderGraphError :: NodeInputSlotAlreadyOccupied {
414
+ node : input_node,
415
+ input_slot : input_index,
416
+ occupied_by_node : * current_output_node,
417
+ } ) ;
418
+ }
275
419
}
276
420
277
421
if output_slot. slot_type != input_slot. slot_type {
@@ -294,9 +438,9 @@ impl RenderGraph {
294
438
let output_node_state = self . get_node_state ( edge. get_output_node ( ) ) ;
295
439
let input_node_state = self . get_node_state ( edge. get_input_node ( ) ) ;
296
440
if let Ok ( output_node_state) = output_node_state {
297
- if output_node_state. edges . output_edges . contains ( edge) {
441
+ if output_node_state. edges . output_edges ( ) . contains ( edge) {
298
442
if let Ok ( input_node_state) = input_node_state {
299
- if input_node_state. edges . input_edges . contains ( edge) {
443
+ if input_node_state. edges . input_edges ( ) . contains ( edge) {
300
444
return true ;
301
445
}
302
446
}
@@ -339,7 +483,7 @@ impl RenderGraph {
339
483
let node = self . get_node_state ( label) ?;
340
484
Ok ( node
341
485
. edges
342
- . input_edges
486
+ . input_edges ( )
343
487
. iter ( )
344
488
. map ( |edge| ( edge, edge. get_output_node ( ) ) )
345
489
. map ( move |( edge, output_node_id) | {
@@ -356,7 +500,7 @@ impl RenderGraph {
356
500
let node = self . get_node_state ( label) ?;
357
501
Ok ( node
358
502
. edges
359
- . output_edges
503
+ . output_edges ( )
360
504
. iter ( )
361
505
. map ( |edge| ( edge, edge. get_input_node ( ) ) )
362
506
. map ( move |( edge, input_node_id) | ( edge, self . get_node_state ( input_node_id) . unwrap ( ) ) ) )
@@ -368,6 +512,12 @@ impl RenderGraph {
368
512
self . sub_graphs . insert ( name. into ( ) , sub_graph) ;
369
513
}
370
514
515
+ /// Removes the `sub_graph` with the `name` from the graph.
516
+ /// If the name does not exist then nothing happens.
517
+ pub fn remove_sub_graph ( & mut self , name : impl Into < Cow < ' static , str > > ) {
518
+ self . sub_graphs . remove ( & name. into ( ) ) ;
519
+ }
520
+
371
521
/// Retrieves the sub graph corresponding to the `name`.
372
522
pub fn get_sub_graph ( & self , name : impl AsRef < str > ) -> Option < & RenderGraph > {
373
523
self . sub_graphs . get ( name. as_ref ( ) )
0 commit comments