Skip to content

Commit

Permalink
add DynamicSceneBundle
Browse files Browse the repository at this point in the history
  • Loading branch information
mockersf committed Jul 2, 2021
1 parent 4a92d43 commit 0f1a3a5
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 12 deletions.
29 changes: 27 additions & 2 deletions crates/bevy_scene/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ use bevy_ecs::{
};
use bevy_transform::components::{GlobalTransform, Transform};

use crate::{InstanceId, Scene, SceneSpawner};
use crate::{DynamicScene, InstanceId, Scene, SceneSpawner};

#[derive(Default, Bundle)]
pub struct SceneBundle {
pub scene: Handle<Scene>,
pub instance_id: Option<InstanceId>,
pub transform: Transform,
pub global_transform: GlobalTransform,
pub instance_id: Option<InstanceId>,
}

#[allow(clippy::type_complexity)]
Expand All @@ -28,3 +28,28 @@ pub fn scene_bundle_spawner(
}
}
}

#[derive(Default, Bundle)]
pub struct DynamicSceneBundle {
pub scene: Handle<DynamicScene>,
pub instance_id: Option<InstanceId>,
pub transform: Transform,
pub global_transform: GlobalTransform,
}

#[allow(clippy::type_complexity)]
pub fn dynamic_scene_bundle_spawner(
mut dynamic_scene_to_spawn: Query<
(Entity, &Handle<DynamicScene>, &mut Option<InstanceId>),
Changed<Handle<DynamicScene>>,
>,
mut scene_spawner: ResMut<SceneSpawner>,
) {
for (entity, dynamic_scene, mut instance) in dynamic_scene_to_spawn.iter_mut() {
if let Some(id) =
instance.replace(scene_spawner.spawn_dynamic_as_child(dynamic_scene.clone(), entity))
{
scene_spawner.despawn_instance(id);
}
}
}
8 changes: 5 additions & 3 deletions crates/bevy_scene/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ pub use scene_spawner::*;
pub mod prelude {
#[doc(hidden)]
pub use crate::{
DynamicScene, Scene, SceneBundle, SceneSpawner, SpawnSceneAsChildCommands,
SpawnSceneCommands,
DynamicScene, DynamicSceneBundle, Scene, SceneBundle, SceneSpawner,
SpawnSceneAsChildCommands, SpawnSceneCommands,
};
}

Expand All @@ -38,6 +38,8 @@ impl Plugin for ScenePlugin {
CoreStage::PreUpdate,
scene_spawner_system.exclusive_system().at_end(),
)
.add_system_to_stage(CoreStage::PreUpdate, scene_bundle_spawner);
// Systems `*_bundle_spawner` must run before `scene_spawner_system`
.add_system_to_stage(CoreStage::PreUpdate, scene_bundle_spawner)
.add_system_to_stage(CoreStage::PreUpdate, dynamic_scene_bundle_spawner);
}
}
38 changes: 31 additions & 7 deletions crates/bevy_scene/src/scene_spawner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub struct SceneSpawner {
spawned_dynamic_scenes: HashMap<Handle<DynamicScene>, Vec<InstanceId>>,
spawned_instances: HashMap<InstanceId, InstanceInfo>,
scene_asset_event_reader: ManualEventReader<AssetEvent<DynamicScene>>,
dynamic_scenes_to_spawn: Vec<Handle<DynamicScene>>,
dynamic_scenes_to_spawn: Vec<(Handle<DynamicScene>, InstanceId)>,
scenes_to_spawn: Vec<(Handle<Scene>, InstanceId)>,
scenes_to_despawn: Vec<Handle<DynamicScene>>,
instances_to_despawn: Vec<InstanceId>,
Expand All @@ -53,7 +53,21 @@ pub enum SceneSpawnError {

impl SceneSpawner {
pub fn spawn_dynamic(&mut self, scene_handle: Handle<DynamicScene>) {
self.dynamic_scenes_to_spawn.push(scene_handle);
let instance_id = InstanceId::new();
self.dynamic_scenes_to_spawn
.push((scene_handle, instance_id));
}

pub fn spawn_dynamic_as_child(
&mut self,
scene_handle: Handle<DynamicScene>,
parent: Entity,
) -> InstanceId {
let instance_id = InstanceId::new();
self.dynamic_scenes_to_spawn
.push((scene_handle, instance_id));
self.scenes_with_parent.push((instance_id, parent));
instance_id
}

pub fn spawn(&mut self, scene_handle: Handle<Scene>) -> InstanceId {
Expand Down Expand Up @@ -251,12 +265,22 @@ impl SceneSpawner {
pub fn spawn_queued_scenes(&mut self, world: &mut World) -> Result<(), SceneSpawnError> {
let scenes_to_spawn = std::mem::take(&mut self.dynamic_scenes_to_spawn);

for scene_handle in scenes_to_spawn {
match self.spawn_dynamic_sync(world, &scene_handle) {
Ok(_) => {}
Err(SceneSpawnError::NonExistentScene { .. }) => {
self.dynamic_scenes_to_spawn.push(scene_handle)
for (scene_handle, instance_id) in scenes_to_spawn {
let mut entity_map = EntityMap::default();

match Self::spawn_dynamic_internal(world, &scene_handle, &mut entity_map) {
Ok(_) => {
self.spawned_instances
.insert(instance_id, InstanceInfo { entity_map });
let spawned = self
.spawned_dynamic_scenes
.entry(scene_handle.clone())
.or_insert_with(Vec::new);
spawned.push(instance_id);
}
Err(SceneSpawnError::NonExistentScene { .. }) => self
.dynamic_scenes_to_spawn
.push((scene_handle, instance_id)),
Err(err) => return Err(err),
}
}
Expand Down

0 comments on commit 0f1a3a5

Please sign in to comment.