Skip to main content

examples/prefabs/
prefab_nested.rs

1use crate::z_ignore_test_common::*;
2
3use flecs_ecs::prelude::*;
4// Nested prefabs make it possible to reuse an existing prefab inside another
5// prefab. An example of where this could be useful is a car with four wheels:
6// instead of defining four times what a wheel is a Car prefab can reference an
7// existing Wheel prefab.
8//
9// Nested prefabs can be created by adding a child that is a variant (inherits
10// from) another prefab. For more information on variants, see the variants
11// example.
12//
13// Instantiated children from a nested prefab still inherit from the original
14// prefab. The reason for this is that an instantiated child is an exact copy
15// of the prefab child, and the prefab child only has an IsA relationship to the
16// nested prefab.
17
18#[derive(Debug, Component, Clone)]
19struct TirePressure {
20    value: f32,
21}
22
23fn main() {
24    let world = World::new();
25
26    // Creates a wheel prefab
27    let wheel = world.prefab_named("Wheel");
28    wheel.set(TirePressure { value: 32.0 });
29
30    // Create a Car prefab with four wheels. Note how we're using the scope
31    // method, which has the same effect as adding the (ChildOf, Car) pair.
32    let car = world.prefab_named("Car");
33    car.run_in_scope(|| {
34        world.prefab_named("FrontLeft").is_a(wheel);
35
36        world.prefab_named("FrontRight").is_a(wheel);
37
38        world.prefab_named("BackLeft").is_a(wheel);
39
40        world.prefab_named("BackRight").is_a(wheel);
41    });
42
43    // Create a prefab instance.
44    let inst_car = world.entity_named("my_car");
45    inst_car.is_a(car);
46
47    // Lookup one of the wheels
48    if let Some(inst) = inst_car.try_lookup_recursive("FrontLeft") {
49        // The type shows that the child has a private copy of the TirePressure
50        // component, and an IsA relationship to the Wheel prefab.
51        println!("{:?}", inst.archetype());
52
53        // Get the TirePressure component & print its value
54        inst.try_get::<Option<&TirePressure>>(|p| {
55            if let Some(p) = p {
56                println!("pressure: {}", p.value);
57            }
58        });
59    } else {
60        println!("entity lookup failed");
61    }
62
63    // Output:
64    //  TirePressure, (Identifier,Name), (ChildOf,my_car), (IsA,Wheel)
65    //  pressure: 32
66}
67
68#[cfg(feature = "flecs_nightly_tests")]
69#[test]
70fn test() {
71    let output_capture = OutputCapture::capture().unwrap();
72    main();
73    output_capture.test("prefab_nested".to_string());
74}