Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_scene/src/scene_component.rs
30635 views
1
use bevy_ecs::{component::Component, reflect::ReflectComponent, template::FromTemplate};
2
use bevy_reflect::Reflect;
3
4
use crate::Scene;
5
6
/// Implemented for [`Component`]s that have an associated [`Scene`], which can be constructed
7
/// with [`Self::Props`].
8
///
9
/// In general, developers should not implement this manually. Instead, they should derive it,
10
/// which also derives [`Component`] and adds additional protections and assurances.
11
///
12
/// See the ["Scene Components"](crate#scene-components) section of the module docs to see how this is used in practice.
13
pub trait SceneComponent: Component + FromTemplate<Template: Default> {
14
/// The "properties" passed into [`Self::scene`] to build the final scene.
15
type Props: Default;
16
17
/// A function that uses the given `props` to produce a [`Scene`]
18
fn scene(props: Self::Props) -> impl Scene;
19
}
20
21
/// Indicates that this entity includes a [`Component`] that must always be spawned with a [`Scene`].
22
#[derive(Component, Default, Clone, Debug, Reflect)]
23
#[cfg_attr(debug_assertions, component(on_add))]
24
#[reflect(Component)]
25
pub struct SceneComponentInfo {
26
spawned_from_scene: bool,
27
#[cfg(debug_assertions)]
28
component_name: &'static str,
29
}
30
31
impl SceneComponentInfo {
32
/// Creates a new [`SceneComponentInfo`] for the given type `C`.
33
pub fn new<C: Component>(spawned_from_scene: bool) -> Self {
34
SceneComponentInfo {
35
spawned_from_scene,
36
#[cfg(debug_assertions)]
37
component_name: core::any::type_name::<C>(),
38
}
39
}
40
}
41
42
impl SceneComponentInfo {
43
#[cfg(debug_assertions)]
44
fn on_add(world: bevy_ecs::world::DeferredWorld, context: bevy_ecs::lifecycle::HookContext) {
45
if let Ok(entity) = world.get_entity(context.entity)
46
&& let Some(component) = entity.get::<SceneComponentInfo>()
47
&& !component.spawned_from_scene
48
{
49
tracing::error!(
50
"Entity {} was spawned with the \"scene component\" {}, but without its scene. \
51
Scene components should not be spawned directly as components. Instead, they \
52
should be spawned as \"scenes\" using world.spawn_scene or commands.spawn_scene. \
53
Scene components should be included using `@{}` syntax in BSN.",
54
context.entity,
55
component.component_name,
56
component.component_name
57
);
58
}
59
}
60
}
61
62