Skip to main content

examples/prefabs/
prefab_slots.rs

1use crate::z_ignore_test_common::*;
2
3use flecs_ecs::prelude::*;
4// Slots can be combined with prefab hierarchies to make it easier to access
5// the child entities created for an instance.
6//
7// To create a slot, the SlotOf relationship is added to the child of a prefab,
8// with as relationship target the prefab for which to register the slot. When
9// the prefab is instantiated, each slot will be added as a relationship pair
10// to the instance that looks like this:
11//   (PrefabChild, InstanceChild)
12//
13// For a SpaceShip prefab and an Engine child, that pair would look like this:
14//   (SpaceShip.Engine, Instance.Engine)
15//
16// To get the entity for a slot, an application can use the regular functions
17// to inspect relationships and relationship targets (see code).
18//
19// Slots can be added to any level of a prefab hierarchy, as long as it is above
20// (a parent of) the slot itself. When the prefab tree is instantiated, the
21// slots are added to the entities that correspond with the prefab children.
22//
23// Without slots, an application would have to rely on manually looking up
24// entities by name to get access to the instantiated children, like what the
25// hierarchy example does.
26
27fn main() {
28    let world = World::new();
29
30    // Create the same prefab hierarchy as from the hierarchy example, but now
31    // with the SlotOf relationship.
32    let spaceship = world.prefab_named("SpaceShip");
33    let engine = world
34        .prefab_named("Engine")
35        .child_of(spaceship)
36        .slot_of(spaceship);
37
38    let cockpit = world
39        .prefab_named("Cockpit")
40        .child_of(spaceship)
41        .slot_of(spaceship);
42
43    // Add an additional child to the Cockpit prefab to demonstrate how
44    // slots can be different from the parent. This slot could have been
45    // added to the Cockpit prefab, but instead we register it on the top
46    // level SpaceShip prefab.
47
48    let pilot_seat = world
49        .prefab_named("PilotSeat")
50        .child_of(cockpit)
51        .slot_of(spaceship);
52
53    // Create a prefab instance.
54    let inst = world.entity_named("my_spaceship").is_a(spaceship);
55
56    // Get the instantiated entities for the prefab slots
57    let inst_engine = inst.target(engine, 0).unwrap();
58    let inst_cockpit = inst.target(cockpit, 0).unwrap();
59    let inst_seat = inst.target(pilot_seat, 0).unwrap();
60
61    println!("instance engine: {}", inst_engine.path().unwrap());
62
63    println!("instance cockpit: {}", inst_cockpit.path().unwrap());
64
65    println!("instance seat: {}", inst_seat.path().unwrap());
66
67    // Output:
68    //  instance engine: ::my_spaceship::Engine
69    //  instance cockpit: ::my_spaceship::Cockpit
70    //  instance seat: ::my_spaceship::Cockpit::PilotSeat
71}
72
73#[cfg(feature = "flecs_nightly_tests")]
74#[test]
75fn test() {
76    let output_capture = OutputCapture::capture().unwrap();
77    main();
78    output_capture.test("prefab_slots".to_string());
79}