17
17
use core:: {
18
18
marker:: PhantomData ,
19
19
ops:: { Deref , DerefMut } ,
20
- ptr:: { slice_from_raw_parts_mut, NonNull } ,
20
+ ptr:: { slice_from_raw_parts , slice_from_raw_parts_mut, NonNull } ,
21
21
} ;
22
22
23
23
use crate :: { archetype:: Archetype , Component , ComponentId , Entity , MissingComponent } ;
@@ -91,121 +91,115 @@ pub struct DynamicComponentInfo {
91
91
pub size : usize ,
92
92
}
93
93
94
- /// The requested access to a dynamic component
95
- #[ derive( Debug , Copy , Clone ) ]
96
- pub struct DynamicComponentAccess {
97
- /// The information related to the component type
98
- pub info : DynamicComponentInfo ,
99
- /// the access required for that component
100
- pub access : Access ,
101
- }
102
-
103
94
const COMPONENT_QUERY_SIZE : usize = 16 ;
104
95
105
96
/// A dynamically constructable component query
106
- #[ derive( Debug , Clone ) ]
107
- pub struct DynamicComponentQuery ( [ Option < DynamicComponentAccess > ; COMPONENT_QUERY_SIZE ] ) ;
108
-
109
- impl Default for DynamicComponentQuery {
110
- fn default ( ) -> Self {
111
- DynamicComponentQuery ( [ None ; COMPONENT_QUERY_SIZE ] )
112
- }
113
- }
114
-
115
- impl std:: ops:: Deref for DynamicComponentQuery {
116
- type Target = [ Option < DynamicComponentAccess > ; COMPONENT_QUERY_SIZE ] ;
117
-
118
- fn deref ( & self ) -> & Self :: Target {
119
- & self . 0
120
- }
121
- }
122
-
123
- impl std:: ops:: DerefMut for DynamicComponentQuery {
124
- fn deref_mut ( & mut self ) -> & mut Self :: Target {
125
- & mut self . 0
126
- }
97
+ #[ derive( Debug , Default , Clone ) ]
98
+ pub struct DynamicComponentQuery {
99
+ /// The list of immutable components to query for
100
+ pub immutable : [ Option < DynamicComponentInfo > ; COMPONENT_QUERY_SIZE ] ,
101
+ /// This list of mutable components to query for
102
+ pub mutable : [ Option < DynamicComponentInfo > ; COMPONENT_QUERY_SIZE ] ,
127
103
}
128
104
129
105
impl Query for DynamicComponentQuery {
130
106
type Fetch = DynamicFetch ;
131
107
}
132
108
133
- /// A [`Fetch`] implementation for dynamic components
134
- #[ derive( Debug ) ]
135
- pub struct DynamicFetch {
136
- datas : [ Option < NonNull < [ u8 ] > > ; COMPONENT_QUERY_SIZE ] ,
109
+ /// The result of a dynamic component query, containing references to the component's bytes
110
+ #[ derive( Default , Debug ) ]
111
+ pub struct DynamicQueryResult < ' a > {
112
+ /// the list of immutable components returned
113
+ pub immutable : [ Option < & ' a [ u8 ] > ; COMPONENT_QUERY_SIZE ] ,
114
+ /// the list of mutable components returned
115
+ pub mutable : [ Option < & ' a mut [ u8 ] > ; COMPONENT_QUERY_SIZE ] ,
137
116
}
138
117
139
- impl Default for DynamicFetch {
140
- fn default ( ) -> Self {
141
- DynamicFetch {
142
- datas : [ None ; COMPONENT_QUERY_SIZE ] ,
143
- }
144
- }
118
+ /// A [`Fetch`] implementation for dynamic components
119
+ #[ derive( Debug , Default , Clone ) ]
120
+ pub struct DynamicFetch {
121
+ immutable : [ Option < NonNull < u8 > > ; COMPONENT_QUERY_SIZE ] ,
122
+ mutable : [ Option < NonNull < u8 > > ; COMPONENT_QUERY_SIZE ] ,
145
123
}
146
124
147
125
impl < ' a > Fetch < ' a > for DynamicFetch {
148
- type Item = [ Option < & ' a mut [ u8 ] > ; COMPONENT_QUERY_SIZE ] ;
126
+ type Item = DynamicQueryResult < ' a > ;
149
127
type State = DynamicComponentQuery ;
150
128
151
- fn access ( archetype : & Archetype , state : & Self :: State ) -> Option < Access > {
129
+ fn access ( archetype : & Archetype , query : & Self :: State ) -> Option < Access > {
152
130
let mut access = None ;
153
131
154
- for component_access in state . iter ( ) . filter_map ( |x| x. as_ref ( ) ) {
155
- if archetype. has_component ( component_access . info . id ) {
156
- access = access . map_or ( Some ( component_access . access ) , |access| {
157
- if access < component_access . access {
158
- Some ( component_access . access )
159
- } else {
160
- Some ( access )
161
- }
162
- } ) ;
132
+ for component in query . immutable . iter ( ) . filter_map ( |& x| x) {
133
+ if archetype. has_component ( component . id ) {
134
+ access = Some ( Access :: Read ) ;
135
+ }
136
+ }
137
+
138
+ for component in query . mutable . iter ( ) . filter_map ( | & x| x ) {
139
+ if archetype . has_component ( component . id ) {
140
+ access = Some ( Access :: Write ) ;
163
141
}
164
142
}
165
143
166
144
access
167
145
}
168
146
169
- fn borrow ( archetype : & Archetype , state : & Self :: State ) {
170
- for component_access in state. iter ( ) . filter_map ( |& x| x) {
171
- archetype. borrow_component ( component_access. info . id ) ;
147
+ fn borrow ( archetype : & Archetype , query : & Self :: State ) {
148
+ for component in query. immutable . iter ( ) . filter_map ( |& x| x) {
149
+ archetype. borrow_component ( component. id ) ;
150
+ }
151
+
152
+ for component in query. mutable . iter ( ) . filter_map ( |& x| x) {
153
+ archetype. borrow_component ( component. id ) ;
172
154
}
173
155
}
174
156
175
- fn release ( archetype : & Archetype , state : & Self :: State ) {
176
- for component_access in state. iter ( ) . filter_map ( |& x| x) {
177
- archetype. release_component ( component_access. info . id ) ;
157
+ fn release ( archetype : & Archetype , query : & Self :: State ) {
158
+ for component in query. immutable . iter ( ) . filter_map ( |& x| x) {
159
+ archetype. release_component ( component. id ) ;
160
+ }
161
+
162
+ for component in query. mutable . iter ( ) . filter_map ( |& x| x) {
163
+ archetype. release_component ( component. id ) ;
178
164
}
179
165
}
180
166
181
- unsafe fn get ( archetype : & ' a Archetype , offset : usize , state : & Self :: State ) -> Option < Self > {
182
- let mut fetch = Self {
183
- datas : [ None ; COMPONENT_QUERY_SIZE ] ,
184
- } ;
167
+ unsafe fn get ( archetype : & ' a Archetype , offset : usize , query : & Self :: State ) -> Option < Self > {
168
+ let mut fetch = Self :: default ( ) ;
185
169
186
170
let mut matches_any = false ;
187
- for ( component_index, component_access) in state
171
+ for ( component_index, component) in query
172
+ . immutable
188
173
. iter ( )
189
174
. enumerate ( )
190
175
. filter_map ( |( i, & x) | x. map ( |y| ( i, y) ) )
191
176
{
192
- let ptr = archetype. get_dynamic (
193
- component_access. info . id ,
194
- component_access. info . size ,
195
- // FIXME: Is this right for the index?
196
- 0 ,
197
- ) ;
177
+ // FIXME: is 0 right for the index?
178
+ let ptr = archetype. get_dynamic ( component. id , component. size , 0 /* index */ ) ;
198
179
199
180
if ptr. is_some ( ) {
200
- matches_any = true
181
+ matches_any = true ;
201
182
}
202
183
203
- fetch. datas [ component_index] = ptr. map ( |x| {
204
- NonNull :: new_unchecked ( slice_from_raw_parts_mut (
205
- x. as_ptr ( ) . add ( offset) ,
206
- component_access. info . size ,
207
- ) )
208
- } ) ;
184
+ fetch. immutable [ component_index] =
185
+ ptr. map ( |x| NonNull :: new_unchecked ( x. as_ptr ( ) . add ( offset) ) ) ;
186
+ }
187
+
188
+ for ( component_index, component) in query
189
+ . mutable
190
+ . iter ( )
191
+ . enumerate ( )
192
+ . filter_map ( |( i, & x) | x. map ( |y| ( i, y) ) )
193
+ {
194
+ // FIXME: is 0 right for the index?
195
+ let ptr = archetype. get_dynamic ( component. id , component. size , 0 /* index */ ) ;
196
+
197
+ if ptr. is_some ( ) {
198
+ matches_any = true ;
199
+ }
200
+
201
+ fetch. mutable [ component_index] =
202
+ ptr. map ( |x| NonNull :: new_unchecked ( x. as_ptr ( ) . add ( offset) ) ) ;
209
203
}
210
204
211
205
if matches_any {
@@ -215,28 +209,42 @@ impl<'a> Fetch<'a> for DynamicFetch {
215
209
}
216
210
}
217
211
218
- unsafe fn next ( & mut self , state : & Self :: State ) -> Self :: Item {
219
- const INIT : Option < & mut [ u8 ] > = None ;
220
- let mut components = [ INIT ; COMPONENT_QUERY_SIZE ] ;
212
+ unsafe fn next ( & mut self , query : & Self :: State ) -> Self :: Item {
213
+ let mut query_result = DynamicQueryResult :: default ( ) ;
221
214
222
- for ( component_index, component_access) in state
215
+ for ( component_index, component) in query
216
+ . immutable
223
217
. iter ( )
224
218
. enumerate ( )
225
219
. filter_map ( |( i, & x) | x. map ( |y| ( i, y) ) )
226
220
{
227
- if let Some ( nonnull) = & mut self . datas [ component_index] {
228
- components[ component_index] = {
229
- let x = nonnull. as_ptr ( ) ;
230
- * nonnull = NonNull :: new_unchecked ( slice_from_raw_parts_mut (
231
- ( x as * mut u8 ) . add ( component_access. info . size ) ,
232
- component_access. info . size ,
233
- ) ) ;
234
- Some ( & mut * x)
235
- } ;
236
- }
221
+ let ptr = self . immutable [ component_index] . expect ( "Expected pointer to component data" ) ;
222
+
223
+ // Increment the pointer for the next iteration
224
+ self . immutable [ component_index] =
225
+ Some ( NonNull :: new_unchecked ( ptr. as_ptr ( ) . add ( component. size ) ) ) ;
226
+
227
+ query_result. immutable [ component_index] =
228
+ Some ( & * slice_from_raw_parts ( ptr. as_ptr ( ) , component. size ) ) ;
229
+ }
230
+
231
+ for ( component_index, component) in query
232
+ . mutable
233
+ . iter ( )
234
+ . enumerate ( )
235
+ . filter_map ( |( i, & x) | x. map ( |y| ( i, y) ) )
236
+ {
237
+ let ptr = self . mutable [ component_index] . expect ( "Expected pointer to component data" ) ;
238
+
239
+ // Increment the pointer for the next iteration
240
+ self . mutable [ component_index] =
241
+ Some ( NonNull :: new_unchecked ( ptr. as_ptr ( ) . add ( component. size ) ) ) ;
242
+
243
+ query_result. mutable [ component_index] =
244
+ Some ( & mut * slice_from_raw_parts_mut ( ptr. as_ptr ( ) , component. size ) ) ;
237
245
}
238
246
239
- components
247
+ query_result
240
248
}
241
249
242
250
unsafe fn should_skip ( & self , _state : & Self :: State ) -> bool {
0 commit comments