33use std:: { alloc:: Layout , any:: TypeId , mem:: size_of, ptr} ;
44
55use anyhow:: Context ;
6- use feather_ecs:: { Ecs } ;
6+ use feather_ecs:: { Archetype , Ecs } ;
77use feather_plugin_host_macros:: host_function;
88use quill_common:: {
99 component:: { ComponentVisitor , SerializationMethod } ,
@@ -44,13 +44,16 @@ struct WrittenComponentData {
4444/// `ComponentVisitor` implementation used to write
4545/// component data to plugin memory.
4646struct WriteComponentsVisitor < ' a > {
47+ ecs : & ' a Ecs ,
48+ types : & ' a [ HostComponent ] ,
4749 cx : & ' a PluginContext ,
4850 num_entities : usize ,
4951}
5052
5153impl < ' a > ComponentVisitor < anyhow:: Result < WrittenComponentData > > for WriteComponentsVisitor < ' a > {
5254 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 ( ) ) ;
5457
5558 // Write each component.
5659 // We use a different strategy depending
@@ -65,7 +68,7 @@ impl<'a> ComponentVisitor<anyhow::Result<WrittenComponentData>> for WriteCompone
6568 // Copy the components into the buffer.
6669 let mut byte_index = 0 ;
6770 for component_slice in components {
68- for component in component_slice. as_slice :: < T > ( ) {
71+ for component in component_slice. iter ( ) {
6972 let bytes = component. as_bytes ( ) ;
7073
7174 unsafe {
@@ -86,7 +89,7 @@ impl<'a> ComponentVisitor<anyhow::Result<WrittenComponentData>> for WriteCompone
8689
8790 // Write components into the buffer.
8891 for component_slice in components {
89- for component in component_slice. as_slice :: < T > ( ) {
92+ for component in component_slice. iter ( ) {
9093 component. to_bytes ( & mut bytes) ;
9194 }
9295 }
@@ -103,12 +106,28 @@ impl<'a> ComponentVisitor<anyhow::Result<WrittenComponentData>> for WriteCompone
103106 }
104107}
105108
109+ fn matching_archetypes < ' a > (
110+ ecs : & ' a Ecs ,
111+ types : & ' a [ HostComponent ] ,
112+ ) -> impl Iterator < Item = & ' a Archetype > + ' a {
113+ struct Has < ' a > ( & ' a Archetype ) ;
114+ impl ComponentVisitor < bool > for Has < ' _ > {
115+ fn visit < T : Component > ( self ) -> bool {
116+ self . 0 . has :: < T > ( )
117+ }
118+ }
119+ ecs. archetypes ( )
120+ . filter ( move |archetype| types. iter ( ) . all ( |t| t. visit ( Has ( archetype) ) ) )
121+ }
122+
106123fn create_query_data (
107124 cx : & PluginContext ,
108125 ecs : & Ecs ,
109126 types : & [ HostComponent ] ,
110127) -> anyhow:: Result < QueryData > {
111- let num_entities = todo ! ( ) ;
128+ let num_entities = matching_archetypes ( ecs, types)
129+ . map ( |archetype| archetype. ids ( ) . len ( ) )
130+ . sum ( ) ;
112131 if num_entities == 0 {
113132 return Ok ( QueryData {
114133 num_entities : 0 ,
@@ -122,6 +141,8 @@ fn create_query_data(
122141 let component_lens = cx. bump_allocate ( Layout :: array :: < u32 > ( types. len ( ) ) ?) ?;
123142 for ( i, & typ) in types. iter ( ) . enumerate ( ) {
124143 let data = typ. visit ( WriteComponentsVisitor {
144+ ecs,
145+ types,
125146 cx,
126147 num_entities,
127148 } ) ?;
@@ -133,7 +154,15 @@ fn create_query_data(
133154 }
134155
135156 let entities_ptr = cx. bump_allocate ( Layout :: array :: < EntityId > ( num_entities) ?) ?;
136- for ( i, entity) in todo ! ( ) . enumerate ( ) {
157+ for ( i, entity) in matching_archetypes ( ecs, types)
158+ . flat_map ( |archetype| {
159+ archetype
160+ . ids ( )
161+ . iter ( )
162+ . map ( |id| unsafe { ecs. find_entity_from_id ( * id) } )
163+ } )
164+ . enumerate ( )
165+ {
137166 let bits = entity. to_bits ( ) . get ( ) ;
138167 unsafe {
139168 cx. write_pod ( entities_ptr. cast ( ) . add ( i) , bits) ?;
0 commit comments