@@ -148,7 +148,7 @@ where
148148 /// We retain these so that, when the entity changes,
149149 /// [`Self::sweep_old_entities`] can quickly find the bin it was located in
150150 /// and remove it.
151- cached_entity_bin_keys : IndexMap < MainEntity , CachedBinKey < BPI > , EntityHash > ,
151+ cached_entity_bin_keys : IndexMap < MainEntity , CachedBinnedEntity < BPI > , EntityHash > ,
152152
153153 /// The set of indices in [`Self::cached_entity_bin_keys`] that are
154154 /// confirmed to be up to date.
@@ -185,10 +185,23 @@ where
185185 /// The entity.
186186 main_entity : MainEntity ,
187187 /// The key that identifies the bin that this entity used to be in.
188- old_bin_key : CachedBinKey < BPI > ,
188+ old_cached_binned_entity : CachedBinnedEntity < BPI > ,
189189}
190190
191191/// Information that we keep about an entity currently within a bin.
192+ pub struct CachedBinnedEntity < BPI >
193+ where
194+ BPI : BinnedPhaseItem ,
195+ {
196+ /// Information that we use to identify a cached entity in a bin.
197+ pub cached_bin_key : Option < CachedBinKey < BPI > > ,
198+ /// The last modified tick of the entity.
199+ ///
200+ /// We use this to detect when the entity needs to be invalidated.
201+ pub change_tick : Tick ,
202+ }
203+
204+ /// Information that we use to identify a cached entity in a bin.
192205pub struct CachedBinKey < BPI >
193206where
194207 BPI : BinnedPhaseItem ,
@@ -200,10 +213,18 @@ where
200213 /// The type of render phase that we use to render the entity: multidraw,
201214 /// plain batch, etc.
202215 pub phase_type : BinnedRenderPhaseType ,
203- /// The last modified tick of the entity.
204- ///
205- /// We use this to detect when the entity needs to be invalidated.
206- pub change_tick : Tick ,
216+ }
217+
218+ impl < BPI > Clone for CachedBinnedEntity < BPI >
219+ where
220+ BPI : BinnedPhaseItem ,
221+ {
222+ fn clone ( & self ) -> Self {
223+ CachedBinnedEntity {
224+ cached_bin_key : self . cached_bin_key . clone ( ) ,
225+ change_tick : self . change_tick ,
226+ }
227+ }
207228}
208229
209230impl < BPI > Clone for CachedBinKey < BPI >
@@ -215,11 +236,21 @@ where
215236 batch_set_key : self . batch_set_key . clone ( ) ,
216237 bin_key : self . bin_key . clone ( ) ,
217238 phase_type : self . phase_type ,
218- change_tick : self . change_tick ,
219239 }
220240 }
221241}
222242
243+ impl < BPI > PartialEq for CachedBinKey < BPI >
244+ where
245+ BPI : BinnedPhaseItem ,
246+ {
247+ fn eq ( & self , other : & Self ) -> bool {
248+ self . batch_set_key == other. batch_set_key
249+ && self . bin_key == other. bin_key
250+ && self . phase_type == other. phase_type
251+ }
252+ }
253+
223254/// How we store and render the batch sets.
224255///
225256/// Each one of these corresponds to a [`GpuPreprocessingMode`].
@@ -504,27 +535,41 @@ where
504535 }
505536 }
506537
507- let new_bin_key = CachedBinKey {
508- batch_set_key,
509- bin_key,
510- phase_type,
538+ // Update the cache.
539+ self . update_cache (
540+ main_entity,
541+ Some ( CachedBinKey {
542+ batch_set_key,
543+ bin_key,
544+ phase_type,
545+ } ) ,
546+ change_tick,
547+ ) ;
548+ }
549+
550+ /// Inserts an entity into the cache with the given change tick.
551+ pub fn update_cache (
552+ & mut self ,
553+ main_entity : MainEntity ,
554+ cached_bin_key : Option < CachedBinKey < BPI > > ,
555+ change_tick : Tick ,
556+ ) {
557+ let new_cached_binned_entity = CachedBinnedEntity {
558+ cached_bin_key,
511559 change_tick,
512560 } ;
513561
514- let ( index, old_bin_key ) = self
562+ let ( index, old_cached_binned_entity ) = self
515563 . cached_entity_bin_keys
516- . insert_full ( main_entity, new_bin_key . clone ( ) ) ;
564+ . insert_full ( main_entity, new_cached_binned_entity . clone ( ) ) ;
517565
518566 // If the entity changed bins, record its old bin so that we can remove
519567 // the entity from it.
520- if let Some ( old_bin_key) = old_bin_key {
521- if old_bin_key. batch_set_key != new_bin_key. batch_set_key
522- || old_bin_key. bin_key != new_bin_key. bin_key
523- || old_bin_key. phase_type != new_bin_key. phase_type
524- {
568+ if let Some ( old_cached_binned_entity) = old_cached_binned_entity {
569+ if old_cached_binned_entity. cached_bin_key != new_cached_binned_entity. cached_bin_key {
525570 self . entities_that_changed_bins . push ( EntityThatChangedBins {
526571 main_entity,
527- old_bin_key ,
572+ old_cached_binned_entity ,
528573 } ) ;
529574 }
530575 }
@@ -826,27 +871,35 @@ where
826871 // reverse order because `swap_remove_index` will potentially invalidate
827872 // all indices after the one we remove.
828873 for index in ReverseFixedBitSetZeroesIterator :: new ( & self . valid_cached_entity_bin_keys ) {
829- let Some ( ( entity, entity_bin_key ) ) =
874+ let Some ( ( entity, cached_binned_entity ) ) =
830875 self . cached_entity_bin_keys . swap_remove_index ( index)
831876 else {
832877 continue ;
833878 } ;
834879
835- remove_entity_from_bin (
836- entity,
837- & entity_bin_key,
838- & mut self . multidrawable_meshes ,
839- & mut self . batchable_meshes ,
840- & mut self . unbatchable_meshes ,
841- & mut self . non_mesh_items ,
842- ) ;
880+ if let Some ( ref cached_bin_key) = cached_binned_entity. cached_bin_key {
881+ remove_entity_from_bin (
882+ entity,
883+ cached_bin_key,
884+ & mut self . multidrawable_meshes ,
885+ & mut self . batchable_meshes ,
886+ & mut self . unbatchable_meshes ,
887+ & mut self . non_mesh_items ,
888+ ) ;
889+ }
843890 }
844891
845892 // If an entity changed bins, we need to remove it from its old bin.
846893 for entity_that_changed_bins in self . entities_that_changed_bins . drain ( ..) {
894+ let Some ( ref old_cached_bin_key) = entity_that_changed_bins
895+ . old_cached_binned_entity
896+ . cached_bin_key
897+ else {
898+ continue ;
899+ } ;
847900 remove_entity_from_bin (
848901 entity_that_changed_bins. main_entity ,
849- & entity_that_changed_bins . old_bin_key ,
902+ old_cached_bin_key ,
850903 & mut self . multidrawable_meshes ,
851904 & mut self . batchable_meshes ,
852905 & mut self . unbatchable_meshes ,
0 commit comments