- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 4.2k
Improved Entity Lifecycle: remove flushing, support manual spawning and despawning #19451
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 71 commits
6a7c2e9
              65a7ea9
              4c6f613
              4eab25c
              8556b19
              f4e06ad
              3df6ab0
              7b044c0
              5c58266
              01d6785
              c100f9e
              ea9a3be
              0c1c9c3
              5a69ebf
              019c154
              58ee663
              85b0d03
              4844dda
              7e39f9d
              9cce28f
              b415dc8
              38a9710
              8956adc
              0c194b7
              180b349
              20a6ee3
              068a2a9
              763877f
              9baf15a
              63effde
              7967807
              866476e
              531658c
              d899b38
              eabc340
              9df7a76
              6a596cb
              5ca8e38
              91f439c
              9d86e69
              d86d241
              d0ed587
              80479d0
              185a6de
              4f956bd
              6bbfee8
              b543a4a
              10f11ba
              e78deec
              5422813
              e1b5386
              271c189
              9de86df
              0b3da34
              fb897d2
              1b6f327
              5085d4f
              20386ff
              4c0d752
              ab0856b
              71675a3
              fdf1b55
              f9b26d6
              e129d77
              d42d9ea
              bac7bd2
              e9df300
              3fcbb24
              d0ca8b1
              4bb74b2
              deb6b4d
              5a058c0
              e73f7bf
              3062966
              01aa792
              caf0581
              9c56341
              9981716
              762c65b
              b743a44
              2add4ca
              97047a9
              fedc90a
              ecf617f
              6d12925
              45780c2
              57816f7
              5c69793
              d8dac49
              26eb50c
              a16cafd
              ac34213
              be9f104
              f525517
              2abdf9e
              4d074e4
              cc71f17
              46e370b
              3781e72
              3d766ae
              9ecbb2d
              dd28156
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -1,20 +1,21 @@ | ||
| use alloc::{boxed::Box, collections::VecDeque, vec::Vec}; | ||
| use bevy_platform::collections::{hash_map::Entry, HashMap, HashSet}; | ||
| use bevy_ptr::{Ptr, PtrMut}; | ||
| use bevy_utils::prelude::DebugName; | ||
| use bumpalo::Bump; | ||
| use core::{any::TypeId, cell::LazyCell, ops::Range}; | ||
| use derive_more::derive::From; | ||
|  | ||
| use crate::{ | ||
| archetype::Archetype, | ||
| bundle::{Bundle, BundleId, InsertMode}, | ||
| component::{Component, ComponentCloneBehavior, ComponentCloneFn, ComponentId, ComponentInfo}, | ||
| entity::{hash_map::EntityHashMap, Entities, Entity, EntityMapper}, | ||
| entity::{hash_map::EntityHashMap, Entity, EntityMapper}, | ||
| query::DebugCheckedUnwrap, | ||
| relationship::RelationshipHookMode, | ||
| world::World, | ||
| }; | ||
| use alloc::{boxed::Box, collections::VecDeque, vec::Vec}; | ||
| use bevy_platform::collections::{hash_map::Entry, HashMap, HashSet}; | ||
| use bevy_ptr::{Ptr, PtrMut}; | ||
| use bevy_utils::prelude::DebugName; | ||
| use bumpalo::Bump; | ||
| use core::{any::TypeId, cell::LazyCell, ops::Range}; | ||
| use derive_more::From; | ||
|  | ||
| use super::{super::world::unsafe_world_cell::UnsafeEntityCell, EntitiesAllocator}; | ||
|  | ||
| /// Provides read access to the source component (the component being cloned) in a [`ComponentCloneFn`]. | ||
| pub struct SourceComponent<'a> { | ||
|  | @@ -78,7 +79,7 @@ pub struct ComponentCloneCtx<'a, 'b> { | |
| target_component_written: bool, | ||
| bundle_scratch: &'a mut BundleScratch<'b>, | ||
| bundle_scratch_allocator: &'b Bump, | ||
| entities: &'a Entities, | ||
| allocator: &'a EntitiesAllocator, | ||
| source: Entity, | ||
| target: Entity, | ||
| component_info: &'a ComponentInfo, | ||
|  | @@ -104,7 +105,7 @@ impl<'a, 'b> ComponentCloneCtx<'a, 'b> { | |
| target: Entity, | ||
| bundle_scratch_allocator: &'b Bump, | ||
| bundle_scratch: &'a mut BundleScratch<'b>, | ||
| entities: &'a Entities, | ||
| allocator: &'a EntitiesAllocator, | ||
| component_info: &'a ComponentInfo, | ||
| entity_cloner: &'a mut EntityClonerState, | ||
| mapper: &'a mut dyn EntityMapper, | ||
|  | @@ -118,7 +119,7 @@ impl<'a, 'b> ComponentCloneCtx<'a, 'b> { | |
| bundle_scratch, | ||
| target_component_written: false, | ||
| bundle_scratch_allocator, | ||
| entities, | ||
| allocator, | ||
| mapper, | ||
| component_info, | ||
| state: entity_cloner, | ||
|  | @@ -271,7 +272,7 @@ impl<'a, 'b> ComponentCloneCtx<'a, 'b> { | |
|  | ||
| /// Queues the `entity` to be cloned by the current [`EntityCloner`] | ||
| pub fn queue_entity_clone(&mut self, entity: Entity) { | ||
| let target = self.entities.reserve_entity(); | ||
| let target = self.allocator.alloc(); | ||
| self.mapper.set_mapped(entity, target); | ||
| self.state.clone_queue.push_back(entity); | ||
| } | ||
|  | @@ -536,12 +537,20 @@ impl EntityCloner { | |
| relationship_hook_insert_mode: RelationshipHookMode, | ||
| ) -> Entity { | ||
| let target = mapper.get_mapped(source); | ||
| // The target may need to be constructed if it hasn't been already. | ||
| // If this fails, it either didn't need to be constructed (ok) or doesn't exist (caught better later). | ||
| let _ = world.construct_empty(target); | ||
|  | ||
| // PERF: reusing allocated space across clones would be more efficient. Consider an allocation model similar to `Commands`. | ||
| let bundle_scratch_allocator = Bump::new(); | ||
| let mut bundle_scratch: BundleScratch; | ||
| { | ||
| let world = world.as_unsafe_world_cell(); | ||
| let source_entity = world.get_entity(source).expect("Source entity must exist"); | ||
| let (source_archetype, source_entity) = world | ||
| .get_entity(source) | ||
| .ok() | ||
| .and_then(|source| source.archetype().map(|archetype| (archetype, source))) | ||
| .expect("Source entity must exist constructed"); | ||
|  | ||
| #[cfg(feature = "bevy_reflect")] | ||
| // SAFETY: we have unique access to `world`, nothing else accesses the registry at this moment, and we clone | ||
|  | @@ -554,14 +563,14 @@ impl EntityCloner { | |
| #[cfg(not(feature = "bevy_reflect"))] | ||
| let app_registry = Option::<()>::None; | ||
|  | ||
| let source_archetype = source_entity.archetype(); | ||
| bundle_scratch = BundleScratch::with_capacity(source_archetype.component_count()); | ||
|  | ||
| let target_archetype = LazyCell::new(|| { | ||
| world | ||
| .get_entity(target) | ||
| .expect("Target entity must exist") | ||
| .archetype() | ||
| .ok() | ||
| .and_then(UnsafeEntityCell::archetype) | ||
| .expect("Target entity must exist constructed") | ||
|          | ||
| }); | ||
|  | ||
| filter.clone_components(source_archetype, target_archetype, |component| { | ||
|  | @@ -598,7 +607,7 @@ impl EntityCloner { | |
| target, | ||
| &bundle_scratch_allocator, | ||
| &mut bundle_scratch, | ||
| world.entities(), | ||
| world.entities_allocator(), | ||
| info, | ||
| state, | ||
| mapper, | ||
|  | ||
Uh oh!
There was an error while loading. Please reload this page.