examples/relationships/relationships_enum.rs
1use crate::z_ignore_test_common::*;
2
3use flecs_ecs::prelude::*;
4// When an enumeration constant is added to an entity, it is added as a relationship
5// pair where the relationship is the enum type, and the target is the constant. For
6// example, this statement:
7// e.add(Color::Red)
8//
9// adds this relationship:
10// (Color, Color::Red)
11//
12// Enums are registered as exclusive relationships, which means that adding an
13// enum constant will replace the previous constant for that enumeration:
14// e.add(Color::Green)
15//
16// will replace Color::Red with Color::Green
17
18//Regular C style enumerations are supported
19// rust style enum variants are not supported *yet* due to limitations in C flecs lib
20// where it expects each enum field to be 4 bytes.
21// I plan on adding support for rust style enums in the future.
22#[derive(Component, Debug, PartialEq)]
23#[repr(C)]
24enum Tile {
25 Grass,
26 Sand,
27 Stone,
28}
29
30#[derive(Component)]
31#[repr(C)]
32enum TileStatus {
33 Free,
34 Occupied,
35}
36
37fn main() {
38 let world = World::new();
39
40 // Create an entity with (Tile, Red) and (TileStatus, Free) relationships
41 let tile = world
42 .entity()
43 .add_enum(Tile::Stone)
44 .add_enum(TileStatus::Free);
45
46 // (Tile, Tile.Stone), (TileStatus, TileStatus.Free)
47 println!("{:?}", tile.archetype());
48
49 // Replace (TileStatus, Free) with (TileStatus, Occupied)
50 tile.add_enum(TileStatus::Occupied);
51
52 // (Tile, Tile.Stone), (TileStatus, TileStatus.Occupied)
53 println!("{:?}", tile.archetype());
54
55 println!();
56
57 // Check if the entity has the Tile relationship and the Tile::Stone pair
58 println!("has tile enum: {}", tile.has::<Tile>()); // true
59 println!(
60 "is the enum from tile stone?: {}",
61 tile.has_enum(Tile::Stone)
62 ); // true
63
64 // Get the current value of the enum
65 tile.try_get::<&Tile>(|tile| {
66 println!("is tile stone: {}", *tile == Tile::Stone); // true
67 });
68
69 // Create a few more entities that we can query
70 world
71 .entity()
72 .add_enum(Tile::Grass)
73 .add_enum(TileStatus::Free);
74
75 world
76 .entity()
77 .add_enum(Tile::Sand)
78 .add_enum(TileStatus::Occupied);
79
80 println!();
81
82 // Iterate all entities with a Tile relationship
83 world
84 .query::<()>()
85 .with_enum_wildcard::<&Tile>()
86 .build()
87 .each_iter(|it, _, _| {
88 let pair = it.pair(0).unwrap();
89 let tile_constant = pair.second_id();
90 println!("{}", tile_constant.path().unwrap());
91 });
92
93 // Output:s:
94 // ::Tile::Stone
95 // ::Tile::Grass
96 // ::Tile::Sand
97
98 println!();
99
100 // Iterate only occupied tiles
101 world
102 .query::<()>()
103 .with_enum_wildcard::<&Tile>()
104 .with_enum(TileStatus::Occupied)
105 .build()
106 .each_iter(|it, _, _| {
107 let pair = it.pair(0).unwrap();
108 let tile_constant = pair.second_id();
109 println!("{}", tile_constant.path().unwrap());
110 });
111
112 // Output:s:
113 // ::Tile::Stone
114 // ::Tile::Sand
115
116 println!();
117
118 // Remove any instance of the TileStatus relationship
119 tile.remove::<TileStatus>();
120
121 // (Tile, Tile.Stone)
122 println!("{:?}", tile.archetype());
123
124 // Total Output:
125 // (relationships_enum.Tile,relationships_enum.Tile.Stone), (relationships_enum.TileStatus,relationships_enum.TileStatus.Free)
126 // (relationships_enum.Tile,relationships_enum.Tile.Stone), (relationships_enum.TileStatus,relationships_enum.TileStatus.Occupied)
127 //
128 // has tile enum: true
129 // is the enum from tile stone?: true
130 // is tile stone: true
131 //
132 // ::relationships_enum::Tile::Stone
133 // ::relationships_enum::Tile::Grass
134 // ::relationships_enum::Tile::Sand
135 //
136 // ::relationships_enum::Tile::Stone
137 // ::relationships_enum::Tile::Sand
138 //
139 // (relationships_enum.Tile,relationships_enum.Tile.Stone)
140}
141
142#[cfg(feature = "flecs_nightly_tests")]
143#[test]
144#[ignore = "is a hierarchy traversal not supported with new get callback"]
145fn test() {
146 let output_capture = OutputCapture::capture().unwrap();
147 main();
148 output_capture.test("relationships_enum".to_string());
149}