Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion crates/bevy_scene2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ pub struct ScenePlugin;
impl Plugin for ScenePlugin {
fn build(&self, app: &mut App) {
app.init_resource::<QueuedScenes>()
.init_resource::<NewScenes>()
.init_asset::<ScenePatch>()
.add_systems(Update, (resolve_scene_patches, spawn_queued).chain());
.add_systems(Update, (resolve_scene_patches, spawn_queued).chain())
.add_observer(on_add_scene_patch_instance);
}
}

Expand Down
56 changes: 34 additions & 22 deletions crates/bevy_scene2/src/spawn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,39 +62,51 @@ pub struct QueuedScenes {
waiting_entities: HashMap<AssetId<ScenePatch>, Vec<Entity>>,
}

#[derive(Resource, Default)]
pub struct NewScenes {
entities: Vec<Entity>,
}

pub fn on_add_scene_patch_instance(
trigger: On<Add, ScenePatchInstance>,
mut new_scenes: ResMut<NewScenes>,
) {
new_scenes.entities.push(trigger.target());
}

pub fn spawn_queued(
world: &mut World,
handles: &mut QueryState<(Entity, &ScenePatchInstance), Added<ScenePatchInstance>>,
handles: &mut QueryState<&ScenePatchInstance>,
mut reader: Local<EventCursor<AssetEvent<ScenePatch>>>,
) {
world.resource_scope(|world, mut patches: Mut<Assets<ScenePatch>>| {
world.resource_scope(|world, mut queued: Mut<QueuedScenes>| {
world.resource_scope(|world, events: Mut<Events<AssetEvent<ScenePatch>>>| {
for (entity, id) in handles
.iter(world)
.map(|(e, h)| (e, h.id()))
.collect::<Vec<_>>()
{
if let Some(scene) = patches.get_mut(id).and_then(|p| p.resolved.as_mut()) {
let mut entity_mut = world.get_entity_mut(entity).unwrap();
scene.spawn(&mut entity_mut).unwrap();
} else {
let entities = queued.waiting_entities.entry(id).or_default();
entities.push(entity);
loop {
let mut new_scenes = world.resource_mut::<NewScenes>();
if new_scenes.entities.is_empty() {
break;
}
for entity in core::mem::take(&mut new_scenes.entities) {
if let Ok(id) = handles.get(world, entity).map(|h| h.id()) {
if let Some(scene) =
patches.get_mut(id).and_then(|p| p.resolved.as_mut())
{
let mut entity_mut = world.get_entity_mut(entity).unwrap();
scene.spawn(&mut entity_mut).unwrap();
} else {
let entities = queued.waiting_entities.entry(id).or_default();
entities.push(entity);
}
}
}
}

for event in reader.read(&events) {
if let AssetEvent::LoadedWithDependencies { id } = event {
let Some(scene) = patches.get_mut(*id).and_then(|p| p.resolved.as_mut())
else {
continue;
};

let Some(entities) = queued.waiting_entities.remove(id) else {
continue;
};

if let AssetEvent::LoadedWithDependencies { id } = event
&& let Some(scene) = patches.get_mut(*id).and_then(|p| p.resolved.as_mut())
&& let Some(entities) = queued.waiting_entities.remove(id)
{
for entity in entities {
if let Ok(mut entity_mut) = world.get_entity_mut(entity) {
scene.spawn(&mut entity_mut).unwrap();
Expand Down