3
3
use std:: { alloc:: Layout , any:: TypeId , mem:: size_of, ptr} ;
4
4
5
5
use anyhow:: Context ;
6
- use feather_ecs:: { Ecs } ;
6
+ use feather_ecs:: { Archetype , Ecs } ;
7
7
use feather_plugin_host_macros:: host_function;
8
8
use quill_common:: {
9
9
component:: { ComponentVisitor , SerializationMethod } ,
@@ -44,13 +44,16 @@ struct WrittenComponentData {
44
44
/// `ComponentVisitor` implementation used to write
45
45
/// component data to plugin memory.
46
46
struct WriteComponentsVisitor < ' a > {
47
+ ecs : & ' a Ecs ,
48
+ types : & ' a [ HostComponent ] ,
47
49
cx : & ' a PluginContext ,
48
50
num_entities : usize ,
49
51
}
50
52
51
53
impl < ' a > ComponentVisitor < anyhow:: Result < WrittenComponentData > > for WriteComponentsVisitor < ' a > {
52
54
fn visit < T : Component > ( self ) -> anyhow:: Result < WrittenComponentData > {
53
- let components = todo ! ( ) ;
55
+ let components = matching_archetypes ( self . ecs , self . types )
56
+ . map ( |archetype| archetype. get :: < T > ( ) . unwrap ( ) ) ;
54
57
55
58
// Write each component.
56
59
// We use a different strategy depending
@@ -65,7 +68,7 @@ impl<'a> ComponentVisitor<anyhow::Result<WrittenComponentData>> for WriteCompone
65
68
// Copy the components into the buffer.
66
69
let mut byte_index = 0 ;
67
70
for component_slice in components {
68
- for component in component_slice. as_slice :: < T > ( ) {
71
+ for component in component_slice. iter ( ) {
69
72
let bytes = component. as_bytes ( ) ;
70
73
71
74
unsafe {
@@ -86,7 +89,7 @@ impl<'a> ComponentVisitor<anyhow::Result<WrittenComponentData>> for WriteCompone
86
89
87
90
// Write components into the buffer.
88
91
for component_slice in components {
89
- for component in component_slice. as_slice :: < T > ( ) {
92
+ for component in component_slice. iter ( ) {
90
93
component. to_bytes ( & mut bytes) ;
91
94
}
92
95
}
@@ -103,12 +106,25 @@ impl<'a> ComponentVisitor<anyhow::Result<WrittenComponentData>> for WriteCompone
103
106
}
104
107
}
105
108
109
+ fn matching_archetypes < ' a > ( ecs : & ' a Ecs , types : & ' a [ HostComponent ] ) -> impl Iterator < Item = & ' a Archetype > + ' a {
110
+ struct Has < ' a > ( & ' a Archetype ) ;
111
+ impl ComponentVisitor < bool > for Has < ' _ > {
112
+ fn visit < T : Component > ( self ) -> bool {
113
+ self . 0 . has :: < T > ( )
114
+ }
115
+ }
116
+ ecs. archetypes ( )
117
+ . filter ( move |archetype| types. iter ( ) . all ( |t| t. visit ( Has ( archetype) ) ) )
118
+ }
119
+
106
120
fn create_query_data (
107
121
cx : & PluginContext ,
108
122
ecs : & Ecs ,
109
123
types : & [ HostComponent ] ,
110
124
) -> anyhow:: Result < QueryData > {
111
- let num_entities = todo ! ( ) ;
125
+ let num_entities = matching_archetypes ( ecs, types)
126
+ . map ( |archetype| archetype. ids ( ) . len ( ) )
127
+ . sum ( ) ;
112
128
if num_entities == 0 {
113
129
return Ok ( QueryData {
114
130
num_entities : 0 ,
@@ -122,6 +138,8 @@ fn create_query_data(
122
138
let component_lens = cx. bump_allocate ( Layout :: array :: < u32 > ( types. len ( ) ) ?) ?;
123
139
for ( i, & typ) in types. iter ( ) . enumerate ( ) {
124
140
let data = typ. visit ( WriteComponentsVisitor {
141
+ ecs,
142
+ types,
125
143
cx,
126
144
num_entities,
127
145
} ) ?;
@@ -133,7 +151,15 @@ fn create_query_data(
133
151
}
134
152
135
153
let entities_ptr = cx. bump_allocate ( Layout :: array :: < EntityId > ( num_entities) ?) ?;
136
- for ( i, entity) in todo ! ( ) . enumerate ( ) {
154
+ for ( i, entity) in matching_archetypes ( ecs, types)
155
+ . flat_map ( |archetype| {
156
+ archetype
157
+ . ids ( )
158
+ . iter ( )
159
+ . map ( |id| unsafe { ecs. find_entity_from_id ( * id) } )
160
+ } )
161
+ . enumerate ( )
162
+ {
137
163
let bits = entity. to_bits ( ) . get ( ) ;
138
164
unsafe {
139
165
cx. write_pod ( entities_ptr. cast ( ) . add ( i) , bits) ?;
0 commit comments