Skip to main content

examples/prefabs/
prefab_variant.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#[derive(Component, Clone)]
21pub struct FreightCapacity {
22    pub value: f32,
23}
24
25#[derive(Component, Clone)]
26pub struct ImpulseSpeed {
27    pub value: f32,
28}
29
30// Prefabs can inherit from each other, which creates prefab variants. With
31// variants applications can reuse a common set of components and specialize it
32// by adding or overriding components on the variant.
33
34fn main() {
35    let world = World::new();
36
37    // Create a base prefab for SpaceShips.
38    let spaceship = world
39        .prefab_named("SpaceShip")
40        .set(ImpulseSpeed { value: 50.0 })
41        .set(Defence { value: 25.0 });
42
43    // Create a Freighter variant which inherits from SpaceShip
44    let freighter = world
45        .prefab_named("Freighter")
46        .is_a(spaceship)
47        .set(FreightCapacity { value: 100.0 })
48        .set(Defence { value: 50.0 });
49
50    // Create a MammotFreighter variant which inherits from Freighter
51    let mammoth_freighter = world
52        .prefab_named("MammothFreighter")
53        .is_a(freighter)
54        .set(FreightCapacity { value: 500.0 });
55
56    // Create a Frigate variant which inherits from SpaceShip
57    world
58        .prefab_named("Frigate")
59        .is_a(spaceship)
60        .set(Attack { value: 100.0 })
61        .set(Defence { value: 75.0 })
62        .set(ImpulseSpeed { value: 125.0 });
63
64    // Create an instance of the MammothFreighter. This entity will inherit the
65    // ImpulseSpeed from SpaceShip, Defence from Freighter and FreightCapacity
66    // from MammothFreighter.
67    let inst = world.entity_named("my_freighter").is_a(mammoth_freighter);
68
69    // Add a private Position component.
70    inst.set(Position { x: 10.0, y: 20.0 });
71
72    // Instances can override inherited components to give them a private copy
73    // of the component. This freighter got an armor upgrade:
74    inst.set(Defence { value: 100.0 });
75
76    // Queries can match components from multiple levels of inheritance
77    world.each_entity::<(&Position, &ImpulseSpeed, &Defence, &FreightCapacity)>(
78        |e, (p, s, d, c)| {
79            println!("{}:", e.name());
80            println!(" - position: {}, {}", p.x, p.y);
81            println!(" - impulse speed: {}", s.value);
82            println!(" - defense: {}", d.value);
83            println!(" - capacity: {}", c.value);
84        },
85    );
86
87    // Output:
88    //   my_freighter:
89    //    - position: 10, 20
90    //    - impulse speed: 50
91    //    - defense: 100
92    //    - capacity: 500
93}
94
95#[cfg(feature = "flecs_nightly_tests")]
96#[test]
97fn test() {
98    let output_capture = OutputCapture::capture().unwrap();
99    main();
100    output_capture.test("prefab_variant".to_string());
101}