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,25 @@ impl<'a> ComponentVisitor<anyhow::Result<WrittenComponentData>> for WriteCompone
103106 }
104107}
105108
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+
106120fn create_query_data (
107121 cx : & PluginContext ,
108122 ecs : & Ecs ,
109123 types : & [ HostComponent ] ,
110124) -> anyhow:: Result < QueryData > {
111- let num_entities = todo ! ( ) ;
125+ let num_entities = matching_archetypes ( ecs, types)
126+ . map ( |archetype| archetype. ids ( ) . len ( ) )
127+ . sum ( ) ;
112128 if num_entities == 0 {
113129 return Ok ( QueryData {
114130 num_entities : 0 ,
@@ -122,6 +138,8 @@ fn create_query_data(
122138 let component_lens = cx. bump_allocate ( Layout :: array :: < u32 > ( types. len ( ) ) ?) ?;
123139 for ( i, & typ) in types. iter ( ) . enumerate ( ) {
124140 let data = typ. visit ( WriteComponentsVisitor {
141+ ecs,
142+ types,
125143 cx,
126144 num_entities,
127145 } ) ?;
@@ -133,7 +151,15 @@ fn create_query_data(
133151 }
134152
135153 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+ {
137163 let bits = entity. to_bits ( ) . get ( ) ;
138164 unsafe {
139165 cx. write_pod ( entities_ptr. cast ( ) . add ( i) , bits) ?;
0 commit comments