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}