@@ -104,6 +104,7 @@ impl AppVisibilityExt for App {
104104
105105 self . add_observer ( update_for_new_clients :: < F > )
106106 . add_observer ( on_insert :: < F > )
107+ . add_observer ( on_client_insert :: < F > )
107108 . add_observer ( on_remove :: < F > )
108109 . add_observer ( on_client_remove :: < F > )
109110 }
@@ -135,26 +136,43 @@ fn on_insert<F: VisibilityFilter>(
135136 entities : Query < ( Entity , & F ) , ( Without < ClientVisibility > , Allow < Disabled > ) > ,
136137 mut clients : Query < ( Entity , Option < & F :: ClientComponent > , & mut ClientVisibility ) > ,
137138) {
139+ // `F` and `F::ClientComponent` could be the same,
140+ // so we need to ensure that it was not inserted into a client
141+ if clients. contains ( insert. entity ) {
142+ return ;
143+ }
144+
138145 let bit = registry. bit :: < F > ( ) ;
139- if let Ok ( ( client, client_component, mut visibility) ) = clients. get_mut ( insert. entity ) {
140- for ( entity, component) in & entities {
141- let visible = component. is_visible ( client, client_component) ;
142- debug ! (
143- "evaluating inserted `{}` to client `{client}` for entity `{entity}` to `{visible}`" ,
144- ShortName :: of:: <F >( ) ,
145- ) ;
146- visibility. set ( entity, bit, visible) ;
147- }
148- } else {
149- let ( entity, component) = entities. get ( insert. entity ) . unwrap ( ) ;
150- for ( client, client_component, mut visibility) in & mut clients {
151- let visible = component. is_visible ( client, client_component) ;
152- debug ! (
153- "evaluating inserted `{}` to entity `{entity}` for client `{client}` to `{visible}`" ,
154- ShortName :: of:: <F >( ) ,
155- ) ;
156- visibility. set ( insert. entity , bit, visible) ;
157- }
146+ let ( entity, component) = entities. get ( insert. entity ) . unwrap ( ) ;
147+ for ( client, client_component, mut visibility) in & mut clients {
148+ let visible = component. is_visible ( client, client_component) ;
149+ debug ! (
150+ "evaluating inserted `{}` to entity `{entity}` for client `{client}` to `{visible}`" ,
151+ ShortName :: of:: <F >( ) ,
152+ ) ;
153+ visibility. set ( insert. entity , bit, visible) ;
154+ }
155+ }
156+
157+ fn on_client_insert < F : VisibilityFilter > (
158+ insert : On < Insert , F :: ClientComponent > ,
159+ registry : Res < FilterRegistry > ,
160+ mut clients : Query < ( & F :: ClientComponent , & mut ClientVisibility ) > ,
161+ entities : Query < ( Entity , & F ) , Without < ClientVisibility > > ,
162+ ) {
163+ let Ok ( ( client_component, mut visibility) ) = clients. get_mut ( insert. entity ) else {
164+ return ;
165+ } ;
166+
167+ let bit = registry. bit :: < F > ( ) ;
168+ for ( entity, component) in & entities {
169+ let visible = component. is_visible ( insert. entity , Some ( client_component) ) ;
170+ debug ! (
171+ "evaluating inserted `{}` to client `{}` for entity `{entity}` to `{visible}`" ,
172+ ShortName :: of:: <F >( ) ,
173+ insert. entity
174+ ) ;
175+ visibility. set ( entity, bit, visible) ;
158176 }
159177}
160178
@@ -165,7 +183,7 @@ fn on_remove<F: VisibilityFilter>(
165183) {
166184 // `F` and `F::ClientComponent` could be the same,
167185 // so we need to ensure that it wasn't removed from a client.
168- if clients. get ( remove. entity ) . is_ok ( ) {
186+ if clients. contains ( remove. entity ) {
169187 return ;
170188 }
171189
@@ -566,6 +584,35 @@ mod tests {
566584 assert ! ( visibility2. get( entity2) . is_hidden( registry) ) ;
567585 }
568586
587+ #[ test]
588+ fn insert_filter_on_client ( ) {
589+ let mut app = App :: new ( ) ;
590+ app. init_resource :: < FilterRegistry > ( )
591+ . init_resource :: < ReplicationRegistry > ( )
592+ . add_visibility_filter :: < SelfFilter > ( )
593+ . add_visibility_filter :: < EntityFilter > ( ) ;
594+
595+ let entity1 = app. world_mut ( ) . spawn ( SelfFilter ) . id ( ) ;
596+ let entity2 = app. world_mut ( ) . spawn ( EntityFilter ) . id ( ) ;
597+
598+ let client = app. world_mut ( ) . spawn ( ClientVisibility :: default ( ) ) . id ( ) ;
599+
600+ let registry = app. world ( ) . resource :: < FilterRegistry > ( ) ;
601+ let visibility = app. world ( ) . get :: < ClientVisibility > ( client) . unwrap ( ) ;
602+
603+ assert ! ( visibility. get( entity1) . is_hidden( registry) ) ;
604+ assert ! ( visibility. get( entity2) . is_hidden( registry) ) ;
605+
606+ app. world_mut ( )
607+ . entity_mut ( client)
608+ . insert ( ( SelfFilter , ClientFilter ) ) ;
609+
610+ let registry = app. world ( ) . resource :: < FilterRegistry > ( ) ;
611+ let visibility = app. world ( ) . get :: < ClientVisibility > ( client) . unwrap ( ) ;
612+ assert ! ( !visibility. get( entity1) . is_hidden( registry) ) ;
613+ assert ! ( !visibility. get( entity2) . is_hidden( registry) ) ;
614+ }
615+
569616 #[ test]
570617 fn remove_filter_from_entity ( ) {
571618 let mut app = App :: new ( ) ;
0 commit comments