1
+ use alloc:: { borrow:: Cow , vec:: Vec } ;
2
+ use core:: marker:: PhantomData ;
3
+
1
4
use crate :: {
5
+ archetype:: ArchetypeComponentId ,
6
+ component:: { ComponentId , Tick } ,
2
7
prelude:: { Bundle , Trigger } ,
3
- system:: System ,
8
+ query:: Access ,
9
+ result:: Result ,
10
+ schedule:: { Fallible , Infallible } ,
11
+ system:: { input:: SystemIn , System } ,
12
+ world:: { unsafe_world_cell:: UnsafeWorldCell , DeferredWorld , World } ,
4
13
} ;
5
14
6
15
use super :: IntoSystem ;
7
16
8
17
/// Implemented for [`System`]s that have a [`Trigger`] as the first argument.
9
- pub trait ObserverSystem < E : ' static , B : Bundle , Out = ( ) > :
18
+ pub trait ObserverSystem < E : ' static , B : Bundle , Out = Result > :
10
19
System < In = Trigger < ' static , E , B > , Out = Out > + Send + ' static
11
20
{
12
21
}
13
22
14
- impl <
15
- E : ' static ,
16
- B : Bundle ,
17
- Out ,
18
- T : System < In = Trigger < ' static , E , B > , Out = Out > + Send + ' static ,
19
- > ObserverSystem < E , B , Out > for T
23
+ impl < E : ' static , B : Bundle , Out , T > ObserverSystem < E , B , Out > for T where
24
+ T : System < In = Trigger < ' static , E , B > , Out = Out > + Send + ' static
20
25
{
21
26
}
22
27
@@ -32,31 +37,158 @@ impl<
32
37
label = "the trait `IntoObserverSystem` is not implemented" ,
33
38
note = "for function `ObserverSystem`s, ensure the first argument is a `Trigger<T>` and any subsequent ones are `SystemParam`"
34
39
) ]
35
- pub trait IntoObserverSystem < E : ' static , B : Bundle , M , Out = ( ) > : Send + ' static {
40
+ pub trait IntoObserverSystem < E : ' static , B : Bundle , M , Out = Result > : Send + ' static {
36
41
/// The type of [`System`] that this instance converts into.
37
42
type System : ObserverSystem < E , B , Out > ;
38
43
39
44
/// Turns this value into its corresponding [`System`].
40
45
fn into_system ( this : Self ) -> Self :: System ;
41
46
}
42
47
43
- impl <
44
- S : IntoSystem < Trigger < ' static , E , B > , Out , M > + Send + ' static ,
45
- M ,
46
- Out ,
47
- E : ' static ,
48
- B : Bundle ,
49
- > IntoObserverSystem < E , B , M , Out > for S
48
+ impl < E , B , M , Out , S > IntoObserverSystem < E , B , ( Fallible , M ) , Out > for S
50
49
where
50
+ S : IntoSystem < Trigger < ' static , E , B > , Out , M > + Send + ' static ,
51
51
S :: System : ObserverSystem < E , B , Out > ,
52
+ E : ' static ,
53
+ B : Bundle ,
52
54
{
53
- type System = < S as IntoSystem < Trigger < ' static , E , B > , Out , M > > :: System ;
55
+ type System = S :: System ;
54
56
55
57
fn into_system ( this : Self ) -> Self :: System {
56
58
IntoSystem :: into_system ( this)
57
59
}
58
60
}
59
61
62
+ impl < E , B , M , S > IntoObserverSystem < E , B , ( Infallible , M ) , Result > for S
63
+ where
64
+ S : IntoSystem < Trigger < ' static , E , B > , ( ) , M > + Send + ' static ,
65
+ S :: System : ObserverSystem < E , B , ( ) > ,
66
+ E : Send + Sync + ' static ,
67
+ B : Bundle ,
68
+ {
69
+ type System = InfallibleObserverWrapper < E , B , S :: System > ;
70
+
71
+ fn into_system ( this : Self ) -> Self :: System {
72
+ InfallibleObserverWrapper :: new ( IntoSystem :: into_system ( this) )
73
+ }
74
+ }
75
+
76
+ /// A wrapper that converts an observer system that returns `()` into one that returns `Ok(())`.
77
+ pub struct InfallibleObserverWrapper < E , B , S > {
78
+ observer : S ,
79
+ _marker : PhantomData < ( E , B ) > ,
80
+ }
81
+
82
+ impl < E , B , S > InfallibleObserverWrapper < E , B , S > {
83
+ /// Create a new `InfallibleObserverWrapper`.
84
+ pub fn new ( observer : S ) -> Self {
85
+ Self {
86
+ observer,
87
+ _marker : PhantomData ,
88
+ }
89
+ }
90
+ }
91
+
92
+ impl < E , B , S > System for InfallibleObserverWrapper < E , B , S >
93
+ where
94
+ S : ObserverSystem < E , B , ( ) > ,
95
+ E : Send + Sync + ' static ,
96
+ B : Bundle ,
97
+ {
98
+ type In = Trigger < ' static , E , B > ;
99
+ type Out = Result ;
100
+
101
+ #[ inline]
102
+ fn name ( & self ) -> Cow < ' static , str > {
103
+ self . observer . name ( )
104
+ }
105
+
106
+ #[ inline]
107
+ fn component_access ( & self ) -> & Access < ComponentId > {
108
+ self . observer . component_access ( )
109
+ }
110
+
111
+ #[ inline]
112
+ fn archetype_component_access ( & self ) -> & Access < ArchetypeComponentId > {
113
+ self . observer . archetype_component_access ( )
114
+ }
115
+
116
+ #[ inline]
117
+ fn is_send ( & self ) -> bool {
118
+ self . observer . is_send ( )
119
+ }
120
+
121
+ #[ inline]
122
+ fn is_exclusive ( & self ) -> bool {
123
+ self . observer . is_exclusive ( )
124
+ }
125
+
126
+ #[ inline]
127
+ fn has_deferred ( & self ) -> bool {
128
+ self . observer . has_deferred ( )
129
+ }
130
+
131
+ #[ inline]
132
+ unsafe fn run_unsafe (
133
+ & mut self ,
134
+ input : SystemIn < ' _ , Self > ,
135
+ world : UnsafeWorldCell ,
136
+ ) -> Self :: Out {
137
+ self . observer . run_unsafe ( input, world) ;
138
+ Ok ( ( ) )
139
+ }
140
+
141
+ #[ inline]
142
+ fn run ( & mut self , input : SystemIn < ' _ , Self > , world : & mut World ) -> Self :: Out {
143
+ self . observer . run ( input, world) ;
144
+ Ok ( ( ) )
145
+ }
146
+
147
+ #[ inline]
148
+ fn apply_deferred ( & mut self , world : & mut World ) {
149
+ self . observer . apply_deferred ( world) ;
150
+ }
151
+
152
+ #[ inline]
153
+ fn queue_deferred ( & mut self , world : DeferredWorld ) {
154
+ self . observer . queue_deferred ( world) ;
155
+ }
156
+
157
+ #[ inline]
158
+ unsafe fn validate_param_unsafe ( & mut self , world : UnsafeWorldCell ) -> bool {
159
+ self . observer . validate_param_unsafe ( world)
160
+ }
161
+
162
+ #[ inline]
163
+ fn initialize ( & mut self , world : & mut World ) {
164
+ self . observer . initialize ( world) ;
165
+ }
166
+
167
+ #[ inline]
168
+ fn update_archetype_component_access ( & mut self , world : UnsafeWorldCell ) {
169
+ self . observer . update_archetype_component_access ( world) ;
170
+ }
171
+
172
+ #[ inline]
173
+ fn check_change_tick ( & mut self , change_tick : Tick ) {
174
+ self . observer . check_change_tick ( change_tick) ;
175
+ }
176
+
177
+ #[ inline]
178
+ fn get_last_run ( & self ) -> Tick {
179
+ self . observer . get_last_run ( )
180
+ }
181
+
182
+ #[ inline]
183
+ fn set_last_run ( & mut self , last_run : Tick ) {
184
+ self . observer . set_last_run ( last_run) ;
185
+ }
186
+
187
+ fn default_system_sets ( & self ) -> Vec < crate :: schedule:: InternedSystemSet > {
188
+ self . observer . default_system_sets ( )
189
+ }
190
+ }
191
+
60
192
#[ cfg( test) ]
61
193
mod tests {
62
194
use crate :: {
0 commit comments