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}