1#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2#![forbid(unsafe_code)]
3#![doc(
4 html_logo_url = "https://bevyengine.org/assets/icon.png",
5 html_favicon_url = "https://bevyengine.org/assets/icon.png"
6)]
7
8extern crate alloc;
15
16mod bundle;
17mod components;
18mod dynamic_scene;
19mod dynamic_scene_builder;
20mod scene;
21mod scene_filter;
22mod scene_loader;
23mod scene_spawner;
24
25#[cfg(feature = "serialize")]
26pub mod serde;
27
28pub use bevy_asset::ron;
30
31use bevy_ecs::schedule::IntoSystemConfigs;
32pub use bundle::*;
33pub use components::*;
34pub use dynamic_scene::*;
35pub use dynamic_scene_builder::*;
36pub use scene::*;
37pub use scene_filter::*;
38pub use scene_loader::*;
39pub use scene_spawner::*;
40
41#[expect(deprecated)]
45pub mod prelude {
46 #[doc(hidden)]
47 pub use crate::{
48 DynamicScene, DynamicSceneBuilder, DynamicSceneBundle, DynamicSceneRoot, Scene,
49 SceneBundle, SceneFilter, SceneRoot, SceneSpawner,
50 };
51}
52
53use bevy_app::prelude::*;
54use bevy_asset::AssetApp;
55
56#[derive(Default)]
58pub struct ScenePlugin;
59
60#[cfg(feature = "serialize")]
61impl Plugin for ScenePlugin {
62 fn build(&self, app: &mut App) {
63 app.init_asset::<DynamicScene>()
64 .init_asset::<Scene>()
65 .init_asset_loader::<SceneLoader>()
66 .init_resource::<SceneSpawner>()
67 .register_type::<SceneRoot>()
68 .register_type::<DynamicSceneRoot>()
69 .add_systems(SpawnScene, (scene_spawner, scene_spawner_system).chain());
70
71 app.world_mut()
73 .register_component_hooks::<DynamicSceneRoot>()
74 .on_remove(|mut world, entity, _| {
75 let Some(handle) = world.get::<DynamicSceneRoot>(entity) else {
76 return;
77 };
78 let id = handle.id();
79 if let Some(&SceneInstance(scene_instance)) = world.get::<SceneInstance>(entity) {
80 let Some(mut scene_spawner) = world.get_resource_mut::<SceneSpawner>() else {
81 return;
82 };
83 if let Some(instance_ids) = scene_spawner.spawned_dynamic_scenes.get_mut(&id) {
84 instance_ids.remove(&scene_instance);
85 }
86 scene_spawner.despawn_instance(scene_instance);
87 }
88 });
89
90 app.world_mut()
92 .register_component_hooks::<SceneRoot>()
93 .on_remove(|mut world, entity, _| {
94 if let Some(&SceneInstance(scene_instance)) = world.get::<SceneInstance>(entity) {
95 let Some(mut scene_spawner) = world.get_resource_mut::<SceneSpawner>() else {
96 return;
97 };
98 scene_spawner.despawn_instance(scene_instance);
99 }
100 });
101 }
102}
103
104#[cfg(not(feature = "serialize"))]
105impl Plugin for ScenePlugin {
106 fn build(&self, _: &mut App) {}
107}