examples/prefabs/
prefab_basics.rs

1use crate::z_ignore_test_common::*;
2
3use flecs_ecs::prelude::*;
4// Prefabs are entities that can be used as templates for other entities. They
5// are created with a builtin Prefab tag, which by default excludes them from
6// queries and systems.
7//
8// Prefab instances are entities that have an IsA relationship to the prefab.
9// The IsA relationship causes instances to inherit the components from the
10// prefab. By default all instances for a prefab share its components.
11//
12// Inherited components save memory as they only need to be stored once for all
13// prefab instances. They also speed up the creation of prefabs, as inherited
14// components don't need to be copied to the instances.
15//
16// To get a private copy of a component, an instance can add it which is called
17// an override. Overrides can be manual (by using add) or automatic (see the
18// auto_override example).
19//
20// If a prefab has children, adding the IsA relationship instantiates the prefab
21// children for the instance (see hierarchy example).
22
23#[derive(Component, Debug)]
24pub struct Defence {
25    pub value: f32,
26}
27
28fn main() {
29    let world = World::new();
30
31    // Add the traits to mark the component to be inherited
32    world
33        .component::<Defence>()
34        .add_trait::<(flecs::OnInstantiate, flecs::Inherit)>();
35
36    // Create a prefab with Position and Velocity components
37    let spaceship = world.prefab_named("Prefab").set(Defence { value: 50.0 });
38
39    // Create a prefab instance
40    let inst = world.entity_named("my_spaceship").is_a_id(spaceship);
41
42    // Because of the IsA relationship, the instance now shares the Defense
43    // component with the prefab, and can be retrieved as a regular component:
44    inst.try_get::<&Defence>(|d_inst| {
45        println!("{:?}", d_inst);
46        // Because the component is shared, changing the value on the prefab will
47        // also change the value for the instance:
48        // this is safe during a table lock because it also has the component and won't cause the table to move.
49        spaceship.set(Defence { value: 100.0 });
50        println!("after set: {:?}", d_inst);
51    });
52
53    // Prefab components can be iterated like regular components:
54    world.each_entity::<&Defence>(|entity, d| {
55        println!("{}: defence: {}", entity.path().unwrap(), d.value);
56    });
57
58    // Output:
59    //  Defence { value: 50.0 }
60    //  after set: Defence { value: 100.0 }
61    //  ::my_spaceship: 100
62}
63
64#[cfg(feature = "flecs_nightly_tests")]
65#[test]
66fn test() {
67    let output_capture = OutputCapture::capture().unwrap();
68    main();
69    output_capture.test("prefab_basics".to_string());
70}