Skip to main content

examples/entities/
entity_prefab.rs

1use crate::z_ignore_test_common::*;
2
3use flecs_ecs::prelude::*;
4
5#[derive(Debug, Component, Clone)]
6pub struct Position {
7    pub x: f32,
8    pub y: f32,
9}
10
11#[derive(Component, Clone)]
12pub struct Attack {
13    pub value: f32,
14}
15
16#[derive(Component, Debug, Clone)]
17pub struct Defence {
18    pub value: f32,
19}
20
21#[derive(Component, Clone)]
22pub struct FreightCapacity {
23    pub value: f32,
24}
25
26#[derive(Component, Clone)]
27pub struct ImpulseSpeed {
28    pub value: f32,
29}
30
31#[derive(Component)]
32pub struct HasFlt;
33
34fn main() {
35    let world = World::new();
36
37    // Add the traits to mark the components to be inherited
38    world
39        .component::<Position>()
40        .add_trait::<(flecs::OnInstantiate, flecs::Inherit)>();
41    world
42        .component::<Defence>()
43        .add_trait::<(flecs::OnInstantiate, flecs::Inherit)>();
44    world
45        .component::<ImpulseSpeed>()
46        .add_trait::<(flecs::OnInstantiate, flecs::Inherit)>();
47    world
48        .component::<FreightCapacity>()
49        .add_trait::<(flecs::OnInstantiate, flecs::Inherit)>();
50    world
51        .component::<HasFlt>()
52        .add_trait::<(flecs::OnInstantiate, flecs::Inherit)>();
53
54    // Create a prefab hierarchy.
55    let spaceship = world
56        .prefab_named("Spaceship")
57        // Add components to prefab entity as usual
58        .set(ImpulseSpeed { value: 50.0 })
59        .set(Defence { value: 50.0 })
60        .set(Position { x: 0.0, y: 0.0 })
61        // By default components in an inheritance hierarchy are shared between
62        // entities. The override function ensures that instances have a private
63        // copy of the component.
64        .auto_override(Position::id());
65
66    let freighter = world
67        .prefab_named("Freighter")
68        .is_a(spaceship)
69        .set(FreightCapacity { value: 100.0 })
70        .set(Defence { value: 100.0 })
71        .add(HasFlt);
72
73    let mammoth_freighter = world
74        .prefab_named("MammothFreighter")
75        .is_a(freighter)
76        .set(FreightCapacity { value: 500.0 })
77        .set(Defence { value: 300.0 });
78
79    world
80        .prefab_named("Frigate")
81        .is_a(spaceship)
82        .add(HasFlt)
83        .set(Attack { value: 100.0 })
84        .set(Defence { value: 75.0 })
85        .set(ImpulseSpeed { value: 125.0 });
86
87    // Create a regular entity from a prefab.
88    // The instance will have a private copy of the Position component, because
89    // of the override in the spaceship entity. All other components are shared.
90    let inst = world
91        .entity_named("my_mammoth_freighter")
92        .is_a(mammoth_freighter);
93
94    // Inspect the type of the entity. This outputs:
95    //    Position,(Identifier,Name),(IsA,MammothFreighter)
96    println!("Instance type: [{}]", inst.archetype());
97
98    // Even though the instance doesn't have a private copy of ImpulseSpeed, we
99    // can still get it using the regular API (outputs 50)
100    inst.try_get::<&ImpulseSpeed>(|impulse_speed| {
101        println!("ImpulseSpeed: {}", impulse_speed.value);
102    });
103
104    // Prefab components can be iterated just like regular components:
105    world.each_entity::<(&ImpulseSpeed, &mut Position)>(|entity, (impulse_speed, position)| {
106        position.x += impulse_speed.value;
107        println!("Entity {}: {:?}", entity.name(), position);
108    });
109
110    // Output:
111    //  Instance type: [Position, (Identifier,Name), (IsA,MammothFreighter)]
112    //  ImpulseSpeed: 50
113    //  Entity my_mammoth_freighter: Position { x: 50.0, y: 0.0 }
114}
115
116#[cfg(feature = "flecs_nightly_tests")]
117#[test]
118fn test() {
119    let output_capture = OutputCapture::capture().unwrap();
120    main();
121    output_capture.test("entity_prefab".to_string());
122}