@@ -2,7 +2,7 @@ use bevy_asset::{Asset, Assets, Handle};
2
2
3
3
use crate :: { pipeline:: RenderPipelines , Texture } ;
4
4
pub use bevy_derive:: ShaderDefs ;
5
- use bevy_ecs:: { Query , Res } ;
5
+ use bevy_ecs:: { Changed , Mut , Query , Res } ;
6
6
7
7
/// Something that can either be "defined" or "not defined". This is used to determine if a "shader def" should be considered "defined"
8
8
pub trait ShaderDef {
@@ -12,7 +12,7 @@ pub trait ShaderDef {
12
12
/// A collection of "shader defs", which define compile time definitions for shaders.
13
13
pub trait ShaderDefs {
14
14
fn shader_defs_len ( & self ) -> usize ;
15
- fn get_shader_def ( & self , index : usize ) -> Option < & str > ;
15
+ fn get_shader_def ( & self , index : usize ) -> Option < ( & str , bool ) > ;
16
16
fn iter_shader_defs ( & self ) -> ShaderDefIterator ;
17
17
}
18
18
@@ -31,7 +31,7 @@ impl<'a> ShaderDefIterator<'a> {
31
31
}
32
32
}
33
33
impl < ' a > Iterator for ShaderDefIterator < ' a > {
34
- type Item = & ' a str ;
34
+ type Item = ( & ' a str , bool ) ;
35
35
36
36
fn next ( & mut self ) -> Option < Self :: Item > {
37
37
loop {
@@ -40,9 +40,7 @@ impl<'a> Iterator for ShaderDefIterator<'a> {
40
40
}
41
41
let shader_def = self . shader_defs . get_shader_def ( self . index ) ;
42
42
self . index += 1 ;
43
- if shader_def. is_some ( ) {
44
- return shader_def;
45
- }
43
+ return shader_def;
46
44
}
47
45
}
48
46
}
@@ -60,55 +58,45 @@ impl ShaderDef for Option<Handle<Texture>> {
60
58
}
61
59
62
60
/// Updates [RenderPipelines] with the latest [ShaderDefs]
63
- pub fn shader_defs_system < T > ( mut query : Query < ( & T , & mut RenderPipelines ) > )
61
+ pub fn shader_defs_system < T > ( mut query : Query < ( & T , & mut RenderPipelines ) , Changed < T > > )
64
62
where
65
63
T : ShaderDefs + Send + Sync + ' static ,
66
64
{
67
- for ( shader_defs, mut render_pipelines) in query. iter_mut ( ) {
68
- for shader_def in shader_defs. iter_shader_defs ( ) {
69
- for render_pipeline in render_pipelines. pipelines . iter_mut ( ) {
70
- render_pipeline
71
- . specialization
72
- . shader_specialization
73
- . shader_defs
74
- . insert ( shader_def. to_string ( ) ) ;
75
- }
76
- }
77
- }
65
+ query. iter_mut ( ) . for_each ( update_render_pipelines)
78
66
}
79
67
80
- /// Clears each [RenderPipelines]' shader defs collection
81
- pub fn clear_shader_defs_system ( mut query : Query < & mut RenderPipelines > ) {
82
- for mut render_pipelines in query. iter_mut ( ) {
68
+ /// Insert defined shader defs and remove undefined ones from render pipelines.
69
+ fn update_render_pipelines < T > ( q : ( & T , Mut < RenderPipelines > ) )
70
+ where
71
+ T : ShaderDefs + Send + Sync + ' static ,
72
+ {
73
+ let ( shader_defs, mut render_pipelines) = q;
74
+ for ( shader_def, is_defined) in shader_defs. iter_shader_defs ( ) {
83
75
for render_pipeline in render_pipelines. pipelines . iter_mut ( ) {
84
- render_pipeline
76
+ let shader_defs = & mut render_pipeline
85
77
. specialization
86
78
. shader_specialization
87
- . shader_defs
88
- . clear ( ) ;
79
+ . shader_defs ;
80
+ let s = shader_def. to_string ( ) ;
81
+ if is_defined {
82
+ shader_defs. insert ( s) ;
83
+ } else {
84
+ shader_defs. remove ( & s) ;
85
+ }
89
86
}
90
87
}
91
88
}
92
89
93
90
/// Updates [RenderPipelines] with the latest [ShaderDefs] from a given asset type
94
91
pub fn asset_shader_defs_system < T : Asset > (
95
92
assets : Res < Assets < T > > ,
96
- mut query : Query < ( & Handle < T > , & mut RenderPipelines ) > ,
93
+ mut query : Query < ( & Handle < T > , & mut RenderPipelines ) , Changed < Handle < T > > > ,
97
94
) where
98
95
T : ShaderDefs + Send + Sync + ' static ,
99
96
{
100
- for ( asset_handle, mut render_pipelines) in query. iter_mut ( ) {
101
- if let Some ( asset_handle) = assets. get ( asset_handle) {
102
- let shader_defs = asset_handle;
103
- for shader_def in shader_defs. iter_shader_defs ( ) {
104
- for render_pipeline in render_pipelines. pipelines . iter_mut ( ) {
105
- render_pipeline
106
- . specialization
107
- . shader_specialization
108
- . shader_defs
109
- . insert ( shader_def. to_string ( ) ) ;
110
- }
111
- }
112
- }
113
- }
97
+ query
98
+ . iter_mut ( )
99
+ // (Handle<T>, _) -> (&T, _)
100
+ . filter_map ( |( h, p) | assets. get ( h) . map ( |a| ( a, p) ) )
101
+ . for_each ( update_render_pipelines) ;
114
102
}
0 commit comments