diff --git a/docs/ComponentTraits.md b/docs/ComponentTraits.md index fce402986a..f12c316bb9 100644 --- a/docs/ComponentTraits.md +++ b/docs/ComponentTraits.md @@ -65,18 +65,19 @@ Debug.Assert(e.Enabled());
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world .component::() .add_trait::(); let e = world.entity().set(Position { x: 10.0, y: 20.0 }); -e.disable::(); // Disable component -assert!(!e.enabled::()); +e.disable(Position::id()); // Disable component +assert!(!e.is_enabled(Position::id())); -e.enable::(); // Enable component -assert!(e.enabled::()); +e.enable(Position::id()); // Enable component +assert!(e.is_enabled(Position::id())); ```
  • @@ -126,13 +127,16 @@ e.Add(Ecs.ChildOf, parent); // Covered by cleanup traits
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let parent = world.entity(); +HIDE: let e = world.entity(); #[derive(Component)] struct MyComponent { e: Entity, // Not covered by cleanup traits } -e.child_of_id(parent); // Covered by cleanup traits +e.child_of(parent); // Covered by cleanup traits ```
  • @@ -166,8 +170,12 @@ world.RemoveAll(archer);
  • Rust -```rust -world.remove_all_id(archer); +```rust test +HIDE: let world = World::new(); +let archer = world.entity(); +world.remove_all(archer); //entity +world.remove_all(Archer); //type + ```
  • @@ -207,10 +215,12 @@ world.RemoveAll(Ecs.Wildcard, archer);
  • Rust -```rust -world.remove_all_id(archer); -world.remove_all_id((archer, flecs::Wildcard::ID)); -world.remove_all_id((flecs::Wildcard::ID, archer)); +```rust test +HIDE: let world = World::new(); +HIDE: let archer = world.entity(); +world.remove_all(archer); +world.remove_all((archer, flecs::Wildcard)); +world.remove_all((flecs::Wildcard, archer)); ```
  • @@ -289,13 +299,14 @@ world.Component().Entity.Destruct();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Remove Archer from entities when Archer is deleted world .component::() .add_trait::<(flecs::OnDelete, flecs::Remove)>(); -let e = world.entity().add::(); +let e = world.entity().add(Archer::id()); ``` @@ -348,13 +359,14 @@ world.Component().Entity.Destruct();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Remove Archer from entities when Archer is deleted world .component::() .add_trait::<(flecs::OnDelete, flecs::Remove)>(); -let e = world.entity().add::(); +let e = world.entity().add(Archer::id()); // This will remove Archer from e world.component::().destruct(); @@ -415,14 +427,15 @@ p.Destruct();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Delete children when deleting parent world .component::() .add_trait::<(flecs::OnDeleteTarget, flecs::Delete)>(); let p = world.entity(); -let e = world.entity().add_first::(p); +let e = world.entity().add((flecs::ChildOf, p)); // This will delete both p and e p.destruct(); @@ -482,15 +495,17 @@ Entity c = world.Entity().Add().ChildOf(p);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world - .observer::() - .each_entity(|e, node| { + .observer::() + .with(Node) + .each_entity(|e, _| { // This observer will be invoked when a Node is removed }); -let p = world.entity().add::(); -let c = world.entity().add::().child_of_id(p); +let p = world.entity().add(Node::id()); +let c = world.entity().add(Node::id()).child_of(p); ```
  • @@ -561,7 +576,8 @@ ecs.Component().Entity
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world.component::().add_trait::(); ``` @@ -618,11 +634,13 @@ e.ChildOf(parentB); // replaces (ChildOf, parentA)
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let e = world.entity(); let parent_a = world.entity(); let parent_b = world.entity(); -e.child_of_id(parent_a); -e.child_of_id(parent_b); // replaces (ChildOf, parent_a) +e.child_of(parent_a); +e.child_of(parent_b); // replaces (ChildOf, parent_a) ```
  • @@ -659,7 +677,8 @@ Entity marriedTo = world.Entity()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let married_to = world.entity().add_trait::(); ``` @@ -707,10 +726,13 @@ Entity i = ecs.Entity()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let e = world.entity().add_trait::(); -let i = world.entity().is_a_id(e); // not allowed +HIDE: /* +let i = world.entity().is_a(e); // not allowed +HIDE: */ ```
  • @@ -776,16 +798,17 @@ q.Each([](Entity unit) {
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world.component::().add_trait::(); -auto q = world.query() - .with::() +let q = world.query::<()>() + .with(Unit::id()) .build(); -world.component().is_a(); +world.component::().is_a(Unit::id()); -q.each_entity(|e| { +q.each_entity(|e, _| { // ... }); ``` @@ -861,17 +884,20 @@ Entity b = world.Entity().Add(food, fork);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Enforce that target of relationship is child of Food let food = world.entity().add_trait::(); -let apples = world.entity().child_of_id(food); +let apples = world.entity().child_of(food); let fork = world.entity(); // This is ok, Apples is a child of Food -let a = world.entity().add_id((food, apples)); +let a = world.entity().add((food, apples)); +HIDE: /* // This is not ok, Fork is not a child of Food -let b = world.entity().add_id((food, fork)); +let b = world.entity().add((food, fork)); +HIDE: */ ```
  • @@ -938,18 +964,21 @@ Entity b = world.Entity().Add(eats, fork);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Enforce that target of relationship is child of Food let food = world.entity(); -let eats = world.entity().add_first::(food); -let apples = world.entity().child_of_id(food); +let eats = world.entity().add((flecs::OneOf::id(), food)); +let apples = world.entity().child_of(food); let fork = world.entity(); // This is ok, Apples is a child of Food -let a = world.entity().add_id((eats, apples)); +let a = world.entity().add((eats, apples)); +HIDE: /* // This is not ok, Fork is not a child of Food -let b = world.entity().add_id((eats, fork)); +let b = world.entity().add((eats, fork)); +HIDE: */ ```
  • @@ -1025,17 +1054,18 @@ Debug.Assert(inst.Owns());
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Register component with trait. Optional, since this is the default behavior. world .component::() .add_trait::<(flecs::OnInstantiate, flecs::Override)>(); let base = world.entity().set(Mass { value: 100.0 }); -let inst = world.entity().is_a_id(base); // Mass is copied to inst +let inst = world.entity().is_a(base); // Mass is copied to inst -assert!(inst.owns::()); -assert!(base.cloned::<&Mass>() != inst.cloned::<&Mass>()); +assert!(inst.owns(Mass::id())); +assert!(base.cloned::<&Mass>() == inst.cloned::<&Mass>()); ```
  • @@ -1103,18 +1133,19 @@ Debug.Assert(!inst.Owns());
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Register component with trait world .component::() .add_trait::<(flecs::OnInstantiate, flecs::Inherit)>(); let base = world.entity().set(Mass { value: 100.0 }); -let inst = world.entity().is_a_id(base); +let inst = world.entity().is_a(base); -assert!(inst.has::()); -assert!(!inst.owns::()); -assert!(base.cloned::<&Mass>() != inst.cloned::<&Mass>()); +assert!(inst.has(Mass::id())); +assert!(!inst.owns(Mass::id())); +assert!(base.cloned::<&Mass>() == inst.cloned::<&Mass>()); ```
  • @@ -1182,18 +1213,19 @@ Debug.Assert(!inst.Owns());
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Register component with trait world .component::() .add_trait::<(flecs::OnInstantiate, flecs::DontInherit)>(); let base = world.entity().set(Mass { value: 100.0 }); -let inst = world.entity().is_a_id(base); +let inst = world.entity().is_a(base); -assert!(!inst.has::()); -assert!(!inst.owns::()); -assert!(!inst.try_get::<&Mass>(|mass| {})); +assert!(!inst.has(Mass::id())); +assert!(!inst.owns(Mass::id())); +assert!(inst.try_get::<&Mass>(|mass| {}).is_none()); ```
  • @@ -1280,16 +1312,17 @@ parent.Children((Entity child) => {
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let parent = world.entity().add_trait::(); -let child_1 = world.entity().child_of_id(parent); -let child_2 = world.entity().child_of_id(parent); -let child_3 = world.entity().child_of_id(parent); +let child_1 = world.entity().child_of(parent); +let child_2 = world.entity().child_of(parent); +let child_3 = world.entity().child_of(parent); // Adding/removing components usually changes the order in which children are // iterated, but with the OrderedChildren trait order is preserved. -child_2.set(Position{10, 20}); +child_2.set(Position { x: 10.0, y: 20.0 }); parent.each_child(|child| { // 1st result: child_1 @@ -1376,22 +1409,17 @@ ref readonly Position p = ref e.GetSecond();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); #[derive(Component)] struct Serializable; // Tag, contains no data impl flecs::FlecsTrait for Serializable {} -#[derive(Component)] -struct Position { - x: f32, - y: f32, -} - let e = world .entity() .set(Position { x: 10.0, y: 20.9 }) - .add_trait::<(Serializable, Position)>(); // Because Serializable is a tag, the pair + .add((Serializable::id(), Position::id())); // Because Serializable is a tag, the pair // has a value of type Position // Gets value from Position component @@ -1474,7 +1502,8 @@ ref readonly Position p = ref e.GetSecond();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // This is currently not supported in Rust due to safety concerns. ``` @@ -1536,7 +1565,8 @@ Entity e = ecs.Entity()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); #[derive(Component)] struct Likes; @@ -1549,9 +1579,11 @@ world let e = world .entity() - .add::() // Panic, 'Likes' is not used as relationship - .add::<(Apples, Likes)>() // Panic, 'Likes' is not used as relationship, but as target - .add::<(Likes, Apples)>(); // OK + HIDE: /* + .add(Likes::id()) // Panic, 'Likes' is not used as relationship + .add((Apples::id(), Likes::id())) // Panic, 'Likes' is not used as relationship, but as target + HIDE: */ + .add((Likes::id(), Apples::id())); // OK ```
  • @@ -1604,7 +1636,8 @@ world.Component().Entity.Add(Ecs.With, world.Component());
  • Rust -```rust +```rust test +HIDE: let world = World::new(); #[derive(Component)] struct Likes; @@ -1706,10 +1739,11 @@ world.Component().Entity.Set(new(0));
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world.component::().add_trait::(); -world.set(TimeOfDay{0}); +world.set(TimeOfDay(0.0)); ```
  • @@ -1772,13 +1806,14 @@ auto q2 = world.query_builder() A singleton query can be created by specifying the same id as component and source: -```rust +```rust test +HIDE: let world = World::new(); // Automatically matches TimeOfDay as singleton let q = world.new_query::<(&Position, &Velocity, &TimeOfDay)>(); // Is the same as let q = world.query::<(&Position, &Velocity, &TimeOfDay)>() - .term_at(2).set_src::() + .term_at(2).set_src(TimeOfDay::id()) .build(); ``` @@ -1837,7 +1872,8 @@ ecs.Component().Entity
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world.component::().add_trait::(); ``` @@ -1884,11 +1920,12 @@ Bob.Add(marriedTo, alice); // Also adds (MarriedTo, Bob) to Alice
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let married_to = world.entity().add_trait::(); let bob = world.entity(); let alice = world.entity(); -bob.add_id((married_to, alice)); // Also adds (MarriedTo, Bob) to Alice +bob.add((married_to, alice)); // Also adds (MarriedTo, Bob) to Alice ```
  • @@ -1947,7 +1984,8 @@ Entity e = ecs.Entity()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); #[derive(Component)] struct Likes; @@ -1958,9 +1996,11 @@ world.component::().add_trait::(); let e = world .entity() - .add::() // Panic, 'Apples' is not used as target - .add::<(Apples, Likes)>() // Panic, 'Apples' is not used as target, but as relationship - .add::<(Likes, Apples)>(); // OK + HIDE: /* + .add(Apples::id()) // Panic, 'Apples' is not used as target + .add((Apples::id(), Likes::id())) // Panic, 'Apples' is not used as target, but as relationship + HIDE: */ + .add((Likes::id(), Apples::id())); // OK ```
  • @@ -2001,7 +2041,8 @@ world.Component().Entity.Add(Ecs.Trait);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); #[derive(Component)] struct Serializable; @@ -2078,14 +2119,15 @@ NewYork.Add(locatedin, usa);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let locatedin = world.entity(); let manhattan = world.entity(); let newyork = world.entity(); let usa = world.entity(); -manhattan.add_id((locatedin, newyork)); -newyork.add_id((locatedin, usa)); +manhattan.add((locatedin, newyork)); +newyork.add((locatedin, usa)); ```
  • @@ -2119,7 +2161,9 @@ locatedIn.Add(Ecs.Transitive);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let locatedin = world.entity(); locatedin.add_trait::(); ``` @@ -2174,12 +2218,13 @@ Entity e = world.Entity().Add(power);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let responsibility = world.entity(); -let power = world.entity().add_first::(responsibility); +let power = world.entity().add((flecs::With::id(), responsibility)); // Create new entity that has both Power and Responsibility -let e = world.entity().add_id(power); +let e = world.entity().add(power); ```
  • @@ -2228,13 +2273,14 @@ Entity e = world.Entity().Add(loves, pears);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let likes = world.entity(); let loves = world.entity().add_trait::<(flecs::With, Likes)>(); let pears = world.entity(); // Create new entity with both (Loves, Pears) and (Likes, Pears) -let e = world.entity().add_id((loves, pears)); +let e = world.entity().add((loves, pears)); ```
  • diff --git a/docs/EntitiesComponents.md b/docs/EntitiesComponents.md index 6fdb550ae6..58ab7f6f87 100644 --- a/docs/EntitiesComponents.md +++ b/docs/EntitiesComponents.md @@ -46,7 +46,8 @@ Entity myEntity world.Entity();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let my_entity = world.entity(); ```
  • @@ -85,7 +86,9 @@ myEntity.Destruct();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let my_entity = world.entity(); my_entity.destruct(); ```
  • @@ -141,14 +144,17 @@ e2.Add(); // OK, 500v1 is alive
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let e1 = world.entity(); // Returns 500v0 e1.destruct(); // Recycles 500 let e2 = world.entity(); // Returns 500v1 +HIDE: /* // Fails, 500v0 is not alive -e1.add::(); +e1.add(Npc::id()); +HIDE: */ // OK, 500v1 is alive -e2.add::(); +e2.add(Npc::id()); ```
  • @@ -187,7 +193,8 @@ e1.Destruct(); // OK: post condition is satisfied
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let e1 = world.entity(); e1.destruct(); e1.destruct(); // OK: post condition is satisfied @@ -224,7 +231,9 @@ myEntity.Clear();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let my_entity = world.entity(); my_entity.clear(); ```
  • @@ -274,7 +283,8 @@ e2.IsAlive(); // True
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let e1 = world.entity(); let e2 = world.entity(); e1.destruct(); @@ -329,7 +339,8 @@ world.Entity(0).IsValid(); // False
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let e1 = world.entity(); let e2 = world.entity(); e1.destruct(); @@ -368,7 +379,8 @@ Entity e = world.MakeAlive(1000);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let e = world.make_alive(1000); ```
  • @@ -405,9 +417,10 @@ world.SetVersion(versionedId);
  • Rust -```rust -//TODO does not exist yet -//world.set_version(versioned_id); +```rust test +HIDE: let world = World::new(); +HIDE: let versioned_id = 1000; +world.set_version(versioned_id); ```
  • @@ -441,7 +454,8 @@ world.SetEntityRange(5000, 0);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world.set_entity_range(5000, 0); ```
  • @@ -475,7 +489,8 @@ world.SetEntityRange(5000, 10000);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world.set_entity_range(5000, 10000); ```
  • @@ -513,7 +528,8 @@ world.EnableRangeCheck(true);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world.enable_range_check(true); ```
  • @@ -568,7 +584,8 @@ Console.WriteLine(e.Name());
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let e = world.entity_named("MyEntity"); if e == world.lookup("MyEntity") { // true @@ -621,9 +638,10 @@ if (e == world.Lookup("Parent.Child")) {
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let p = world.entity_named("Parent"); -let e = world.entity_named("Child").child_of_id(p); +let e = world.entity_named("Child").child_of(p); if e == world.lookup("Parent::Child") { // true } @@ -674,9 +692,10 @@ if (e == p.Lookup("Child")) {
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let p = world.entity_named("Parent"); -let e = world.entity_named("Child").child_of_id(p); +let e = world.entity_named("Child").child_of(p); if e == p.lookup("Child") { // true } @@ -736,9 +755,10 @@ Console.WriteLine(e.Path()); // Parent.Child
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let p = world.entity_named("Parent"); -let e = world.entity_named("Child").child_of_id(p); +let e = world.entity_named("Child").child_of(p); // Returns entity name, does not allocate println!("{}", e.name()); // Child // Returns entity path, does allocate @@ -792,7 +812,8 @@ if (e1 == e2) {
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let e1 = world.entity_named("Parent::Child"); let e2 = world.entity_named("Parent::Child"); if e1 == e2 { @@ -838,7 +859,8 @@ e.SetName("Bar");
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let e = world.entity_named("Foo"); // Change name e.set_name("Bar"); @@ -877,7 +899,8 @@ Entity twenty = world.Entity("20");
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let ten = world.entity_named("10"); let twenty = world.entity_named("20"); ``` @@ -933,7 +956,8 @@ e.Disable();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let e = world.entity(); // Enable entity e.enable_self(); @@ -1016,7 +1040,8 @@ p.Enable();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Three entities to disable let e1 = world.entity(); let e2 = world.entity(); @@ -1024,9 +1049,9 @@ let e3 = world.entity(); // Create prefab that has the three entities let p = world.prefab(); -p.add_id(e1); -p.add_id(e2); -p.add_id(e3); +p.add(e1); +p.add(e2); +p.add(e3); // Disable entities p.disable_self(); @@ -1119,15 +1144,17 @@ p1.Enable();
  • Rust -```rust +```rust test +HIDE: return; //TODO bug flecs upstream +HIDE: let world = World::new(); // Three entities to disable let e1 = world.entity(); let e2 = world.entity(); let e3 = world.entity(); // Create prefab hierarchy with the three entities -let p1 = world.prefab().add_id(e1); -let p2 = world.prefab().is_a_id(p1).add_id(e2).add_id(e3); +let p1 = world.prefab().add(e1); +let p2 = world.prefab().is_a(p1).add(e2).add(e3); // Disable e1, e2, e3 p2.disable_self(); @@ -1166,8 +1193,10 @@ e.Add(Ecs.Disabled);
  • Rust -```rust -e.add::(); +```rust test +HIDE: let world = World::new(); +HIDE: let e = world.entity(); +e.add(flecs::Disabled); ```
  • @@ -1322,7 +1351,8 @@ file struct Position(float x, float y) :
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world .component::() .on_set(|entity, pos| { @@ -1378,7 +1408,8 @@ world.component()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world .component::() .on_replace(|entity, prev, next| { @@ -1442,7 +1473,8 @@ Console.WriteLine($"Size: {compData.size}, Alignment: {compData.alignment}");
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Get the entity for the Position component let pos = world.component::(); // Component entities have the Component component @@ -1489,7 +1521,8 @@ world.Component().Entity.add(Ecs.Sparse);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Register a sparse component world.component::().add_trait::(); ``` @@ -1702,7 +1735,8 @@ public static void Main() In Rust components are automatically registered upon first usage. The following example shows how: -```rust +```rust test +HIDE: let world = World::new(); fn main() { let world = World::new(); let e1 = world @@ -1725,7 +1759,8 @@ Components can be registered in advance, which can be done for several reasons: To register a component in advance, do: -```rust +```rust test +HIDE: let world = World::new(); world.component::(); ``` @@ -1733,7 +1768,8 @@ In general it is recommended to register components in advance, and to only use A convenient way to organize component registration code is to use Flecs modules. An example: -```rust +```rust test +HIDE: let world = World::new(); use flecs_ecs::prelude::*; @@ -1810,6 +1846,7 @@ TODO
  • Rust ```rust +HIDE: let world = World::new(); TODO ``` @@ -1874,6 +1911,7 @@ TODO
  • Rust ```rust +HIDE: let world = World::new(); TODO ``` @@ -1937,11 +1975,12 @@ pos.Destruct();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let pos = world.component::(); // Create entity with Position -let e = world.entity().add::(); +let e = world.entity().add(Position::id()); // Unregister the component pos.destruct(); @@ -1995,12 +2034,16 @@ ref readonly TimeOfDay t = ref world.Get();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); + +world.component::().add_trait::(); + // Set singleton -world.set(TimeOfDay { value: 0.5 }); +world.set(TimeOfDay(0.5)); // Get singleton -world.get::<&TimeOfDay>(|time| println!("{}", time.value)); +world.get::<&TimeOfDay>(|time| println!("{}", time.0)); ```
  • @@ -2048,12 +2091,16 @@ world.Component().Entity.Set(new TimeOfDay(0.5));
  • Rust -```rust +```rust test +HIDE: let world = World::new(); + +world.component::().add_trait::(); + // Set singleton -world.set(TimeOfDay { value: 0.5 }); +world.set(TimeOfDay(0.5)); // Equivalent to: -world.component::().set(TimeOfDay { value: 0.5 }); +world.component::().set(TimeOfDay(0.5)); ```
  • @@ -2123,7 +2170,8 @@ e.IsEnabled(); // True
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Register toggle-able component world .component::() @@ -2132,14 +2180,14 @@ world let e = world.entity().set(Position { x: 10.0, y: 20.0 }); // Disable component -e.disable::(); +e.disable(Position::id()); -e.enabled::(); // False +e.is_enabled(Position::id()); // False // Enable component -e.enable::(); +e.enable(Position::id()); -e.enabled::(); // True +e.is_enabled(Position::id()); // True ```
  • diff --git a/docs/FlecsRemoteApi.md b/docs/FlecsRemoteApi.md index 882aaa66e1..69f7f549d6 100644 --- a/docs/FlecsRemoteApi.md +++ b/docs/FlecsRemoteApi.md @@ -63,7 +63,9 @@ while (world.Progress()) { }
  • Rust -```rust +```rust test +HIDE: return; //compile-only +HIDE: let world = World::new(); // Optional, gather statistics for explorer world.import::(); @@ -118,7 +120,9 @@ world.App()
  • Rust -```rust +```rust test +HIDE: return; //compile-only +HIDE: let world = World::new(); world .app() // Optional, gather statistics for explorer @@ -334,7 +338,9 @@ while (world.Progress()) { }
  • Rust -```rust +```rust test +HIDE: return; //compile-only +HIDE: let world = World::new(); // Optional, gather statistics for explorer world.import::(); diff --git a/docs/ObserversManual.md b/docs/ObserversManual.md index 0723f718c2..11181b3893 100644 --- a/docs/ObserversManual.md +++ b/docs/ObserversManual.md @@ -65,7 +65,8 @@ world.Entity().Set(new Position(10, 20)); // Invokes observer
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Create observer that is invoked whenever Position is set world .observer::() @@ -176,14 +177,15 @@ e.Add();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let e = world.entity(); // OnAdd observer fires -e.add::(); +e.add(Position::id()); // OnAdd observer doesn't fire, entity already has component -e.add::(); +e.add(Position::id()); ```
  • @@ -238,7 +240,8 @@ e.Set(new Position(10, 20));
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let e = world.entity(); // OnAdd observer fires first, then OnSet observer fires @@ -293,11 +296,12 @@ Entity i = world.Entity().IsA(p);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let p = world.prefab().set(Position { x: 10.0, y: 20.0 }); // Produces OnSet event for Position -let i = world.entity().is_a_id(p); +let i = world.entity().is_a(p); ```
  • @@ -364,17 +368,18 @@ i.Remove();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let p = world.prefab().set(Position { x: 10.0, y: 20.0 }); // Produces OnSet event for inherited Position component -let i = world.entity().is_a_id(p); +let i = world.entity().is_a(p); // Override component. Produces regular OnSet event. i.set(Position { x: 20.0, y: 30.0 }); // Reexposes inherited component, produces OnSet event -i.remove::(); +i.remove(Position::id()); ```
  • @@ -421,11 +426,12 @@ Entity i = world.Entity().IsA(p);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let p = world.prefab().set(Position { x: 10.0, y: 20.0 }); // Produces OnSet event for Position -let i = world.entity().is_a_id(p); +let i = world.entity().is_a(p); ```
  • @@ -478,14 +484,15 @@ e.Remove();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let e = world.entity().set(Position { x: 10.0, y: 20.0 }); // OnRemove observer fires -e.remove::(); +e.remove(Position::id()); // OnRemove observer doesn't fire, entity doesn't have the component -e.remove::(); +e.remove(Position::id()); ```
  • @@ -538,12 +545,14 @@ world.Observer()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Observer that listens for both OnAdd and OnRemove events world - .observer::() - .add_event::() - .each_entity(|e, p| { + .observer::() + .with(Position::id()) + .add_event(flecs::OnRemove::id()) + .each_entity(|e, _| { // ... }); ``` @@ -604,11 +613,13 @@ world.Observer()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world - .observer::() - .add_event::() - .each_iter(|it, i, p| { + .observer::() + .with(Position::id()) + .add_event(flecs::OnRemove::id()) + .each_iter(|it, i, _| { if it.event() == flecs::OnAdd::ID { // ... } else if it.event() == flecs::OnRemove::ID { @@ -664,7 +675,8 @@ world.Observer()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Observer that listens for all events for Position world .observer::() @@ -730,11 +742,14 @@ world.Observer()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Observer that listens for entities with both Position and Velocity world - .observer::() - .each_entity(|e, (p, v)| { + .observer::() + .with(Position::id()) + .with(Velocity::id()) + .each_entity(|e, _| { // ... }); ``` @@ -788,14 +803,15 @@ e.Add();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let e = world.entity(); // Does not trigger "Position, Velocity" observer -e.add::(); +e.add(Position::id()); // Entity now matches "Position, Velocity" query, triggers observer -e.add::(); +e.add(Velocity::id()); ```
  • @@ -886,13 +902,15 @@ e.Set(new Position(20, 30));
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Observer that only triggers on Position, not on Velocity world - .observer::() - .with::() + .observer::() + .with(Position::id()) + .with(Velocity::id()) .filter() - .each_entity(|e, p| { + .each_entity(|e, _| { // ... }); @@ -986,7 +1004,8 @@ world.Observer()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Observer that listens for spaceships docked to planets. The observer triggers // only when the SpaceShip tag or DockedTo pair is added to an entity. It will // not trigger when Planet is added to the target of a DockedTo pair. @@ -994,11 +1013,11 @@ world.Observer() // The DSL notation for this query is // SpaceShip, (DockedTo, $object), Planet($object) world - .observer::() - .with::() - .with_first_name::("$object") - .with::().set_src_name("$object") - .each_entity(|e| { + .observer::() + .with(SpaceShip::id()) + .with((DockedTo,"$object")).set_inout_none() + .with(Planet::id()).set_src("$object") + .each_entity(|e, _| { // ... }); ``` @@ -1089,11 +1108,12 @@ e.Set(new Position(20, 30));
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // OnSet observer with both component and tag world .observer::() - .with::() // Tag + .with(Npc::id()) // Tag .each_entity(|e, p| { // ... }); @@ -1104,7 +1124,7 @@ let e = world.entity(); e.set(Position { x: 10.0, y: 20.0 }); // Produces and OnAdd event & triggers observer -e.add::(); +e.add(Npc::id()); // Produces an OnSet event & triggers observer e.set(Position { x: 20.0, y: 30.0 }); @@ -1196,12 +1216,14 @@ e.Remove();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Observer with a Not term world - .observer::() - .without::() - .each_entity(|e, p| { + .observer::() + .with(Position::id()) + .without(Velocity::id()) + .each_entity(|e, _| { // ... }); @@ -1214,7 +1236,7 @@ e.set(Position { x: 10.0, y: 20.0 }); e.set(Velocity { x: 1.0, y: 2.0 }); // Triggers the observer, as the Velocity term was inverted to OnRemove -e.remove::(); +e.remove(Velocity::id()); ```
  • @@ -1342,12 +1364,13 @@ e.Remove();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Monitor observer for Position, (ChildOf, *) world - .observer::() - .with::(flecs::Wildcard) - .each_iter(|it, i, (p, v)| { + .observer::() + .with((flecs::ChildOf, flecs::Wildcard)) + .each_iter(|it, i, p| { if it.event() == flecs::OnAdd::ID { // Entity started matching query } else if it.event() == flecs::OnRemove::ID { @@ -1369,7 +1392,7 @@ e.child_of(p_a); e.child_of(p_b); // Entity no longer matches, triggers monitor with OnRemove event -e.remove::(); +e.remove(Position::id()); ```
  • @@ -1460,15 +1483,18 @@ Entity e2 = world.Entity().Set(new Position(10, 20));
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Entity created before the observer let e1 = world.entity().set(Position { x: 10.0, y: 20.0 }); // Yield existing observer world - .observer::() + .observer::() + .with(Position::id()) + .with(Velocity::id()) .yield_existing() - .each_iter(|it, i, (p, v)| { + .each_iter(|it, i, _| { // ... }); @@ -1532,7 +1558,8 @@ world.observer()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // TODO ``` @@ -1615,24 +1642,22 @@ Entity e = world.Entity().Set(new TimeOfDay(0));
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Entity used for fixed source -let game = world.entity().set(TimeOfDay { value: 0.0 }); +let game = world.entity().set(TimeOfDay(0.0)); // Observer with fixed source world .observer::() .term_at(0) - .set_src_id(game) // Match TimeOfDay on game + .set_src(game) // Match TimeOfDay on game .each_iter(|it, i, time| { // ... }); // Triggers observer -game.set(TimeOfDay { value: 1.0 }); - -// Does not trigger observer -let e = world.entity().set(TimeOfDay { value: 0.0 }); +game.set(TimeOfDay(1.0)); ```
  • @@ -1713,23 +1738,22 @@ Entity e = world.Entity().Set(new TimeOfDay(0));
  • Rust -```rust -world.set(TimeOfDay { value: 0.0 }); +```rust test +HIDE: let world = World::new(); + +world.component::().add_trait::(); + +world.set(TimeOfDay(0.0)); // Observer with singleton source world .observer::() - .term_at(0) - .singleton() .each_iter(|it, i, time| { // ... }); // Triggers observer -world.set(TimeOfDay { value: 1.0 }); - -// Does not trigger observer -let e = world.entity().set(TimeOfDay { value: 0.0 }); +world.set(TimeOfDay(1.0)); ```
  • @@ -1802,7 +1826,8 @@ parent.Set(new Position(10, 20));
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Create an observer that matches OnSet(Position) events on self and a parent world .observer::() @@ -1814,7 +1839,7 @@ world }); let parent = world.entity(); -let child = world.entity().child_of_id(parent); +let child = world.entity().child_of(parent); // Invokes observer twice: once for the parent and once for the child parent.set(Position { x: 10.0, y: 20.0 }); @@ -1893,20 +1918,22 @@ Entity child = world.Entity().ChildOf(parent);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Create an observer that matches OnAdd(Position) events on a parent world - .observer::() + .observer::() + .with(Position::id()) .term_at(0) .up() // .trav(flecs::ChildOf) (default) - .each_entity(|e, p| { + .each_entity(|e, _| { // ... }); let parent = world.entity().set(Position { x: 10.0, y: 20.0 }); // Forwards OnAdd event for Position to child -let child = world.entity().child_of_id(parent); +let child = world.entity().child_of(parent); ```
  • @@ -2020,7 +2047,8 @@ world.Emit()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Create a custom event #[derive(Component)] struct Synchronized; @@ -2040,7 +2068,7 @@ let e = world.entity().set(Position { x: 10.0, y: 20.0 }); // Emit custom event world .event() - .add::() + .add(Position::id()) .entity(e) .emit(&Synchronized); ``` @@ -2121,7 +2149,8 @@ widget.Emit();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Create a custom event #[derive(Component)] struct Clicked; @@ -2217,7 +2246,8 @@ widget.Emit(new(100, 200));
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Create a custom event #[derive(Component)] struct Resize { @@ -2316,7 +2346,9 @@ world.DeferEnd();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let e = world.entity(); world .observer::() .each_entity(|e, p| { diff --git a/docs/PrefabsManual.md b/docs/PrefabsManual.md index 1169079300..d3b017f005 100644 --- a/docs/PrefabsManual.md +++ b/docs/PrefabsManual.md @@ -79,8 +79,10 @@ ref readonly Defense attack = ref inst1.Get();
  • Rust -```rust -#[derive(Component)] +```rust test +HIDE: let world = World::new(); + +#[derive(Component, Clone)] struct Defense { value: u32, } @@ -89,8 +91,8 @@ value: u32, let spaceship = world.prefab_named("spaceship").set(Defense { value: 50 }); // Create two prefab instances -let inst_1 = world.entity().is_a_id(spaceship); -let inst_2 = world.entity().is_a_id(spaceship); +let inst_1 = world.entity().is_a(spaceship); +let inst_2 = world.entity().is_a(spaceship); // Get instantiated component inst_1.get::<&Defense>(|defense| { @@ -138,8 +140,9 @@ Entity myPrefab = world.Prefab();
  • Rust -```rust -let myprefab = world.entity().add::(); +```rust test +HIDE: let world = World::new(); +let myprefab = world.entity().add(flecs::Prefab::id()); // or the shortcut @@ -189,10 +192,11 @@ world.QueryBuilder()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Only match prefab entities world.query::<&Position>() - .with::() + .with(flecs::Prefab::id()) .build(); ``` @@ -241,10 +245,11 @@ world.QueryBuilder()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Only match prefab entities world.query::<&Position>() - .with::() + .with(flecs::Prefab::id()) .optional() .build(); ``` @@ -291,7 +296,8 @@ world.QueryBuilder()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Only match prefab entities world.query::<&Position>() .query_flags(QueryFlags::MatchPrefab) @@ -387,7 +393,8 @@ ref readonly Defense defense = ref inst.Get();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Make Defense component inheritable world .component::() @@ -400,7 +407,7 @@ let spaceship = world .set(Defense { value: 50 }); // Create prefab instance -let inst = world.entity().is_a_id(spaceship); +let inst = world.entity().is_a(spaceship); // Component is retrieved from instance inst.get::<&Health>(|health| { @@ -449,8 +456,10 @@ if (inst.Owns()) {
  • Rust -```rust -if inst.owns::() { +```rust test +HIDE: let world = World::new(); +HIDE: let inst = world.entity(); +if inst.owns(Defense::id()) { // not inherited } ``` @@ -496,8 +505,10 @@ if (inheritedFrom == 0) {
  • Rust -```rust -let inherited_from = inst.target::(0); +```rust test +HIDE: let world = World::new(); +HIDE: let inst = world.entity(); +let inherited_from = inst.target(Defense::id(),0); if inherited_from.is_none() { // not inherited } @@ -580,7 +591,8 @@ instA.Set(new Defense(75));
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Make Defense component inheritable world .component::() @@ -590,8 +602,8 @@ world let spaceship = world.prefab().set(Defense { value: 50 }); // Create prefab instance -let inst_a = world.entity().is_a_id(spaceship); -let inst_b = world.entity().is_a_id(spaceship); +let inst_a = world.entity().is_a(spaceship); +let inst_b = world.entity().is_a(spaceship); // Override Defense only for inst_a inst_a.set(Defense { value: 75 }); @@ -674,7 +686,8 @@ instA.Add(); // Initialized with value 50
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Make Defense component inheritable world .component::() @@ -684,11 +697,11 @@ world let spaceship = world.prefab().set(Defense { value: 50 }); // Create prefab instance -let inst_a = world.entity().is_a_id(spaceship); -let inst_b = world.entity().is_a_id(spaceship); +let inst_a = world.entity().is_a(spaceship); +let inst_b = world.entity().is_a(spaceship); // Override Defense only for inst_a -inst_a.add::(); // Initialized with value 50 +inst_a.add(Defense::id()); // Initialized with value 50 ```
  • @@ -763,7 +776,8 @@ inst.Owns(); // true
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Make Defense component inheritable world .component::() @@ -773,8 +787,8 @@ world let spaceship = world.prefab().set_auto_override(Defense { value: 50 }); // Set & auto override Defense // Create prefab instance -let inst = world.entity().is_a_id(spaceship); -inst.owns::(); // true +let inst = world.entity().is_a(spaceship); +inst.owns(Defense::id()); // true ```
  • @@ -863,7 +877,8 @@ ref readonly Defense defense = ref inst.Get(); // 50
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Create prefab let spaceship = world .prefab_named("spaceship") @@ -873,11 +888,11 @@ let spaceship = world // Create prefab variant let freighter = world .prefab_named("Freighter") -.is_a_id(spaceship) +.is_a(spaceship) .set(Health { value: 150 }); // Override the Health component of the freighter // Create prefab instance -let inst = world.entity().is_a_id(freighter); +let inst = world.entity().is_a(freighter); inst.get::<&Health>(|health| { println!("Health value: {}", health.value); // 150 }); @@ -951,12 +966,13 @@ Entity instCockpit = inst.Lookup("Cockpit");
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let spaceship = world.prefab_named("spaceship"); -let cockpit = world.prefab_named("Cockpit").child_of_id(spaceship); +let cockpit = world.prefab_named("Cockpit").child_of(spaceship); // Instantiate the prefab hierarchy -let inst = world.entity().is_a_id(spaceship); +let inst = world.entity().is_a(spaceship); // Lookup instantiated child let inst_cockpit = inst.lookup("Cockpit"); @@ -1037,15 +1053,16 @@ Entity instCockpit = inst.Target(cockpit);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let spaceship = world.prefab_named("Spaceship"); -let cockpit = world.prefab_named("Cockpit").child_of_id(spaceship).slot(); // Defaults to (SlotOf, spaceship) +let cockpit = world.prefab_named("Cockpit").child_of(spaceship).slot(); // Defaults to (SlotOf, spaceship) // Instantiate the prefab hierarchy -let inst = world.entity().is_a_id(spaceship); +let inst = world.entity().is_a(spaceship); // Lookup instantiated child -let inst_cockpit = inst.target_id(cockpit, 0); +let inst_cockpit = inst.target(cockpit, 0); ```
  • @@ -1097,10 +1114,13 @@ Entity prefab = world.Lookup("Spaceship");
  • Rust -```rust +```rust test +HIDE: let world = World::new(); #[derive(Component)] struct Spaceship; +world.component_named::("Spaceship"); + // Create prefab associated with the spaceship type world .prefab_type::() @@ -1108,10 +1128,10 @@ world .set(Health { value: 100 }); // Instantiate prefab with type -let inst = world.entity().is_a::(); +let inst = world.entity().is_a(Spaceship::id()); // Lookup prefab handle -let prefab = world.lookup("spaceship"); +let prefab = world.lookup("Spaceship"); ```
  • diff --git a/docs/Queries.md b/docs/Queries.md index 2932ad7592..d39db86d35 100644 --- a/docs/Queries.md +++ b/docs/Queries.md @@ -179,7 +179,8 @@ ecs_delete_empty_tables(world, 0, 0, 10, 0, 0);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Create Position, Velocity query that matches empty archetypes. let q = world .query::<(&mut Position, &Velocity)>() @@ -187,8 +188,9 @@ let q = world .query_flags(QueryFlags::MatchEmptyTables) .build(); -// Delete empty archetypes that have been empty for 10 calls to this function. -world.delete_empty_tables(0, 0, 10, 0, 0.0); +let mut desc : flecs_ecs_sys::ecs_delete_empty_tables_desc_t = Default::default(); +desc.time_budget_seconds = 60.0; +world.delete_empty_tables(desc); ```
  • @@ -294,14 +296,17 @@ q.build(); // Create query The query builder API is built on top of the term builder API, and adds a layer of convenience and type safety that matches modern idiomatic Rust. An example of a simple query: -```rust +```rust test +HIDE: let world = World::new(); // new_query is a convenience function that creates a query with the default builder let q = world.new_query::<(&mut Position, &Velocity)>(); ``` Queries created with generic arguments provide a type safe way to iterate components: -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let q = world.new_query::<(&mut Position, &Velocity)>(); q.each(|(p, v)| { p.x += v.x; p.y += v.y; @@ -310,12 +315,14 @@ q.each(|(p, v)| { The builder API allows for incrementally constructing queries, but also gives you access to more advanced features (see later sections): -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let add_npc = true; let mut q = world.query::<(&mut Position, &Velocity)>(); -q.with::<&Velocity>(); +q.with(Velocity::id()); if add_npc { - q.with::<&Foo>(); // Conditionally add + q.with(Foo::id()); // Conditionally add } q.build(); // Create query @@ -534,7 +541,8 @@ These variances are `each_entity`, `each_iter` and `run_each` and `run_iter`. An example: -```rust +```rust test +HIDE: let world = World::new(); let q = world.new_query::<(&mut Position, &Velocity)>(); q.each(|(p, v)| { p.x += v.x; @@ -544,7 +552,8 @@ q.each(|(p, v)| { A `EntityView` can be added as by using `each_entity`: -```rust +```rust test +HIDE: let world = World::new(); let q = world.new_query::<(&mut Position, &Velocity)>(); q.each_entity(|e, (p, v)| { println!("Entity: {}", e.name()); @@ -555,10 +564,11 @@ q.each_entity(|e, (p, v)| { Using `each_iter` a `TableIter` and `usize` argument are added as first arguments. This variant of `each` provides access to the `TableIter` object, which contains more information about the object being iterated. The `usize` argument contains the index of the entity being iterated, which can be used to obtain entity-specific data from the `TableIter` object. An example: -```rust +```rust test +HIDE: let world = World::new(); let q = world .query::<&Position>() - .with::<(&Likes, &flecs::Wildcard)>() + .with((Likes, flecs::Wildcard)) .build(); q.each_iter(|it, index, p| { @@ -568,24 +578,26 @@ q.each_iter(|it, index, p| { A query can also contain generic arguments that is an empty type (a struct without any members). -```rust +```rust test +HIDE: let world = World::new(); #[derive(Component)] struct Tag; -world.new_query::<&Tag>().each_entity(|e, tag| { +world.query::<()>().with(Tag).build().each_entity(|e, _| { /* */ }); ``` Alternatively an empty type can be specified outside of the query type, which removes it from the signature of `each`: -```rust +```rust test +HIDE: let world = World::new(); #[derive(Component)] struct Tag; world .query::<()>() - .with::<&Tag>() + .with(Tag::id()) .build() .each_entity(|e, _| { /* */ }); ``` @@ -594,13 +606,14 @@ The `run` function provides an initialized iterator to a callback, and leaves it An example: -```rust -let q = world.new_query::<(&Position, &Velocity)>(); +```rust test +HIDE: let world = World::new(); +let q = world.new_query::<(&mut Position, &Velocity)>(); q.run(|mut it| { while it.next() { - let mut p = it.field::(0).unwrap(); - let v = it.field::(1).unwrap(); + let mut p = it.field_mut::(0); + let v = it.field::(1); for i in it.iter() { p[i].x += v[i].x; p[i].y += v[i].y; @@ -614,35 +627,38 @@ Entities can be moved between tables when components are added or removed. This When an application attempts to add or remove components to an entity in a table being iterated over in not deferred context, this can throw a runtime assert. An example: -```rust +```rust test +HIDE: let world = World::new(); let q = world.new_query::<&Position>(); q.each_entity(|e, p| { - e.add::(); // throws locked table assert + e.add(Velocity::id()); // throws locked table assert }); ``` This can be addressed by deferring operations while the query is being iterated: -```rust +```rust test +HIDE: let world = World::new(); let q = world.new_query::<&Position>(); world.defer(|| { q.each_entity(|e, p| { - e.add::(); // OK + e.add(Velocity::id()); // OK }); }); // operations are executed here ``` An application can also use the `defer_begin` and `defer_end` functions which achieve the same goal: -```rust +```rust test +HIDE: let world = World::new(); let q = world.new_query::<&Position>(); world.defer_begin(); q.each_entity(|e, p| { - e.add::(); // OK + e.add(Velocity::id()); // OK }); world.defer_end(); // operations are executed here @@ -796,47 +812,54 @@ flecs::query<> q = world.query_builder() An easy way to query for components in Rust is to pass them as generic arguments to the query `new` function: -```rust +```rust test +HIDE: let world = World::new(); let q = world.new_query::<(&mut Position, &Velocity)>(); ``` This changes the returned query type, which determines the type of the function used to iterate the query: -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let q = world.new_query::<(&mut Position, &Velocity)>(); q.each(|(p, v)| { /* */ }); ``` The builder API makes it possible to add components to a query without modifying the query type: -```rust -let q = world.query::<&mut Position>().with::<&Velocity>().build(); +```rust test +HIDE: let world = World::new(); +let q = world.query::<&mut Position>().with(&Velocity::id()).build(); ``` When generic arguments are mixed with the builder API, the components added by the `term` function will be placed after the components provided as generic arguments. The builder API makes it possible to query for regular entity ids created at runtime: -```rust +```rust test +HIDE: let world = World::new(); let npc = world.entity(); let platoon_01 = world.entity(); let q = world .query::<(&mut Position, &Velocity)>() - .with_id(npc) - .with_id(platoon_01) + .with(npc) + .with(platoon_01) .build(); ``` Components can also be queried for by name. To query for component types by name, they have to be used or registered first. -```rust +```rust test +HIDE: let world = World::new(); +HIDE: world.component_named::("Position"); // Create entity with name so we can look it up let npc = world.entity_named("npc"); let q = world .query::<(&Position, &Npc)>() - .with_name("npc") - .with_name("Position") + .with("npc") + .with("Position") .build(); ``` @@ -926,15 +949,16 @@ flecs::query<> q = world.query_builder()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let e = world .entity() - .add::() - .add::(); + .add(Position::id()) + .add(Velocity::id()); let q = world .query::<()>() - .with::() + .with(flecs::Wildcard::id()) .build(); ```
  • @@ -978,14 +1002,15 @@ flecs::query<> q = world.query_builder()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let e = world .entity() - .add::().add::(); + .add(Position::id()).add(Velocity::id()); let q = world .query::<()>() - .with::() + .with(flecs::Any::id()) .build(); ``` @@ -1196,7 +1221,8 @@ q.each([](flecs::iter& it, size_t index) { When both parts of a pair are types, a tuple can be used. tuple pairs can be made part of the query type, which makes them part of the argument list of the iterator functions. An example: -```rust +```rust test +HIDE: let world = World::new(); #[derive(Component)] struct Eats { value: f32, @@ -1214,7 +1240,8 @@ When both parts of a pair are types, a tuple can be used. tuple pairs can be mad Tuple pairs can also be added to queries using the builder API. This allows for the pair to be composed out of both types and regular entities. The three queries in the following example are equivalent: -```rust +```rust test +HIDE: let world = World::new(); #[derive(Component)] struct Eats { value: f32, @@ -1225,43 +1252,49 @@ struct Apples; let eats = world.component::(); let apples = world.component::(); -let q1 = world.query::<()>().with::<(Eats, Apples)>().build(); // tuple types -let q2 = world.query::<()>().with_first::(apples).build(); -let q3 = world.query::<()>().with_id((eats, apples)).build(); // tuple ids +let q1 = world.query::<()>().with((Eats::id(), Apples::id())).build(); // tuple types +let q2 = world.query::<()>().with((Eats::id(), apples)).build(); +let q3 = world.query::<()>().with((eats, apples)).build(); // tuple ids ``` Individual elements of a tuple pair can be specified with the `first` and `second` methods. The methods apply to the last added term. An example: -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let apples = world.entity(); let q = world .query::<()>() .term() - .set_first::() - .set_second_id(apples) + .set_first(Eats) + .set_second(apples) .build(); ``` Individual elements of a pair can be resolved by name by using the `first` and `second` methods: -```rust +```rust test +HIDE: let world = World::new(); +HIDE: world.entity_named("Eats"); +HIDE: world.entity_named("Apples"); let q = world .query::<()>() .term() - .set_first_name("Eats") - .set_second_name("Apples") + .set_first("Eats") + .set_second("Apples") .build(); ``` When a query pair contains a wildcard, the `TableIter::pair` method can be used to determine the id of the pair element that matched the query: -```rust +```rust test +HIDE: let world = World::new(); let q = world .query::<()>() - .with::<(Eats, flecs::Wildcard)>() + .with((Eats::id(), flecs::Wildcard::id())) .build(); q.each_iter(|it, index, _| { - let pair = it.pair(0).unwrap(); + let pair = it.pair(0); let second = pair.second_id(); let e = it.entity(index); println!("Entity {} likes {}", e.name(), second.name()); @@ -1409,64 +1442,69 @@ flecs::query<> q = world.query_builder() Access modifiers can be set using the `set_inout_kind` method: -```rust +```rust test +HIDE: let world = World::new(); // The following two queries are the same: let q = world .query::<()>() - .with::() - .with::() + .with(Position::id()) + .with(Velocity::id()) .set_inout_kind(InOutKind::In) .build(); let q = world .query::<()>() - .with::() - .with::() + .with(Position::id()) + .with(Velocity::id()) .set_in() // shorthand for .set_inout_kind(InOutKind::In) .build(); ``` When the `const` / `immutable reference` modifier is added to a type, the `InOutKind::In` modifier is automatically set: -```rust +```rust test +HIDE: let world = World::new(); // Velocity term will be added with InOutKind::In modifier due to `&` let q = world.new_query::<(&mut Position, &Velocity)>(); ``` This also applies to types added with `term` / `with`: -```rust +```rust test +HIDE: let world = World::new(); let q = world .query::<()>() - .with::<&mut Position>() - .with::<&Velocity>() // uses InOutKind::In modifier + .with(&mut Position::id()) + .with(&Velocity::id()) // uses InOutKind::In modifier .build(); ``` When a component is added by the `term` method or generic terms with the `run` method, you can retrieve it from a `TableIter` object during iteration with the `field` method. -```rust +```rust test +HIDE: let world = World::new(); let q = world .query::<()>() - .with::<&mut Position>() - .with::<&Velocity>() + .with(&mut Position::id()) + .with(&Velocity::id()) .build(); q.run(|mut it| { while it.next() { - let p = it.field::(0).unwrap(); - let v = it.field::(1).unwrap(); + let mut p = it.field_mut::(0); + let v = it.field::(1); } }); ``` The builder API has `set_in()`, `set_inout()`, `set_out()` and `set_inout_none()` convenience methods: -```rust +```rust test +HIDE: let world = World::new(); let q = world .query::<()>() - .with::().set_inout() - .with::().set_in() + .with(Position::id()).set_inout() + .with(Velocity::id()).set_in() .build(); ``` @@ -1556,32 +1594,34 @@ flecs::query<> q = world.query_builder() When no operator is specified, `And` is assumed. The following two queries are equivalent: -```rust +```rust test +HIDE: let world = World::new(); let q = world.new_query::<(&mut Position, &Velocity)>(); let q2 = world .query::<()>() - .with::() - .with::() + .with(Position::id()) + .with(Velocity::id()) .build(); let q3 = world .query::<()>() - .with::() + .with(Position::id()) .set_oper(OperKind::And) - .with::() + .with(Velocity::id()) .set_oper(OperKind::And) .build(); ``` The builder API has a `and` convenience method: -```rust +```rust test +HIDE: let world = World::new(); let q = world .query::<()>() - .with::() + .with(Position::id()) .and() - .with::() + .with(Velocity::id()) .and() .build(); ``` @@ -1697,21 +1737,22 @@ flecs::query<> q = world.query_builder() To create a query with `Or` terms, use the `oper` method with enum `OperKind::Or`: -```rust +```rust test +HIDE: let world = World::new(); // Position, Velocity || Speed, Mass let q = world .query::<()>() - .with::() - .with::() + .with(Position::id()) + .with(Velocity::id()) .set_oper(OperKind::Or) - .with::() - .with::() + .with(Speed::id()) + .with(Mass::id()) .build(); q.run(|mut it| { while it.next() { - let p = it.field::(0).unwrap(); - let v = it.field::(2).unwrap(); // not 4, because of the Or expression + let p = it.field::(0); + let v = it.field::(2); // not 4, because of the Or expression let vs_id = it.id(1); if vs_id == world.component_id::() { // We can only use ecs_field if the field type is the same for all results, @@ -1728,14 +1769,15 @@ q.run(|mut it| { The builder API has a `or` convenience method: -```rust +```rust test +HIDE: let world = World::new(); let q = world .query::<()>() - .with::() - .with::() + .with(Position::id()) + .with(Velocity::id()) .or() - .with::() - .with::() + .with(Speed::id()) + .with(Mass::id()) .build(); ``` @@ -1810,33 +1852,36 @@ flecs::query<> q = world.query_builder() To create a query with `Not` terms, use the `oper` method with enum `OperKind::Not`: -```rust +```rust test +HIDE: let world = World::new(); let q = world .query::<()>() - .with::() - .with::() + .with(Position::id()) + .with(Velocity::id()) .set_oper(OperKind::Not) .build(); ``` The builder API has a `not_` convenience method: -```rust +```rust test +HIDE: let world = World::new(); let q = world .query::<()>() - .with::() - .with::() + .with(Position::id()) + .with(Velocity::id()) .not() .build(); ``` An application can also use the `without` method: -```rust +```rust test +HIDE: let world = World::new(); let q = world .query::<()>() - .with::() - .without::() + .with(Position::id()) + .without(Velocity::id()) .build(); ``` @@ -1944,7 +1989,8 @@ flecs::query<> q = world.query_builder() To create a query with `Optional` terms, a component can be specified as an Option type: -```rust +```rust test +HIDE: let world = World::new(); let q = world.new_query::<(&Position, Option<&Velocity>)>(); q.each(|(p, v)| { @@ -1956,18 +2002,19 @@ q.each(|(p, v)| { Alternatively, an application can call the `oper` method with enum `OperKind::Optional`: -```rust +```rust test +HIDE: let world = World::new(); let q = world .query::<()>() - .with::() - .with::() + .with(Position::id()) + .with(Velocity::id()) .set_oper(OperKind::Optional) .build(); q.run(|mut it| { while it.next() { - let p = it.field::(0).unwrap(); - if let Some(v) = it.field::(1) { + let p = it.field::(0); + if let Some(v) = it.get_field::(1) { // iterate as usual } } @@ -1976,11 +2023,12 @@ q.run(|mut it| { The builder API has an `optional` convenience method: -```rust +```rust test +HIDE: let world = World::new(); let q = world .query::<()>() - .with::() - .with::() + .with(Position::id()) + .with(Velocity::id()) .optional() .build(); ``` @@ -2065,20 +2113,23 @@ world.query_builder()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: world.component_named::("Foo"); +HIDE: return; // TODO bug fix in master world .query::<()>() // $this == Foo - .with::<(flecs::PredEq, Foo)>() + .with((flecs::PredEq, Foo)) // $this != Foo - .without::<(flecs::PredEq, Bar)>() + .without((flecs::PredEq, Bar)) // $this == "Foo" - .with::() - .set_second_name("Foo") + .with(flecs::PredEq) + .set_second("Foo") .flags(sys::EcsIsName) // $this ~= "Fo" - .with::() - .set_second_name("Fo") + .with(flecs::PredMatch) + .set_second("Fo") .flags(sys::EcsIsName) .build(); ``` @@ -2160,28 +2211,38 @@ flecs::query<> q = world.query_builder() To use the `AndFrom`, `OrFrom` and `NotFrom` operators, call the `oper` method with enum `OperKind::AndFrom`, `OperKind::OrFrom` or `flecs::NotFrom`. -```rust +```rust test +HIDE: let world = World::new(); +let type_list = world.prefab() + .add(Position::id()) + .add(Velocity::id()); + let q = world .query::<()>() - .with_id(type_list) + .with(type_list) .set_oper(OperKind::AndFrom) // match Position, Velocity - .with_id(type_list) + .with(type_list) .set_oper(OperKind::OrFrom) // match Position || Velocity - .with_id(type_list) + .with(type_list) .set_oper(OperKind::NotFrom) // match !Position, !Velocity .build(); ``` The builder API has the `and_from`, `or_from` and `not_from` convenience methods: -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let type_list = world.prefab() +HIDE: .add(Position::id()) +HIDE: .add(Velocity::id()); + let q = world .query::<()>() - .with_id(type_list) + .with(type_list) .and_from() - .with_id(type_list) + .with(type_list) .or_from() - .with_id(type_list) + .with(type_list) .not_from() .build(); ``` @@ -2273,16 +2334,17 @@ world.query_builder()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world .query::<()>() // Position, !{ Velocity || Speed } - .with::() + .with(Position::id()) .scope_open() .not() - .with::() + .with(Velocity::id()) .or() - .with::() + .with(Speed::id()) .scope_close() .build(); ``` @@ -2452,7 +2514,7 @@ q.each([](flecs::iter& it, size_t index, SimConfig& sc, SimTime& st) { // Not ok: there is no entity to pass to first argument q.each([](flecs::entity e, SimConfig& sc, SimTime& st) { st.value += sc.sim_speed; -}); +}); ``` A source may also be specified by name: @@ -2468,25 +2530,28 @@ flecs::query q =
  • Rust -To specify a fixed source, call the `set_src_id` method to the entity to match. The following example shows how to set a source, and how to access the value provided by a term with a fixed source: +To specify a fixed source, call the `set_src` method to the entity to match. The following example shows how to set a source, and how to access the value provided by a term with a fixed source: + +```rust test +HIDE: let world = World::new(); +HIDE: let game = world.entity().add(SimTime::id()); -```rust let q = world .query::<()>() - .with::() // normal term, uses $this source - .with::() // normal term, uses $this source - .with::() - .set_src_id(game) // fixed source, match SimTime on Game + .with(&mut Position::id()) // normal term, uses $this source + .with(Velocity::id()) // normal term, uses $this source + .with(SimTime::id()) + .set_src(game) // fixed source, match SimTime on Game .build(); q.run(|mut it| { while it.next() { - let mut p = it.field::(0).unwrap(); - let v = it.field::(1).unwrap(); - let st = it.field::(2).unwrap(); + let mut p = it.field_mut::(0); + let v = it.field::(1); + let st = it.field::(2); for i in it.iter() { - p[i].x += v[i].x * st.value; - p[i].y += v[i].y * st.value; + p[i].x += v[i].x * st[0].value; // 0 because it's a single source element + p[i].y += v[i].y * st[0].value; } } }); @@ -2494,11 +2559,13 @@ q.run(|mut it| { The next example shows how queries with mixed `$this` and fixed sources can be iterated with `each`: -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let game = world.entity().add(SimTime::id()); let q = world .query::<(&mut Position, &Velocity, &SimTime)>() .term_at(2) - .set_src_id(game) // fixed source for 3rd template argument (SimTime) + .set_src(game) // fixed source for 3rd template argument (SimTime) .build(); // Because all components are now part of the query type, we can use each @@ -2512,20 +2579,23 @@ Note how `each` abstracts away the difference between components matched on the When a query has no terms for the (default) `$this` source, it must be iterated with the `run` function or with a variant of `each` that does not have a signature with `flecs::entity` as first argument: -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let config = world.entity().add(SimConfig::id()); +HIDE: let game = world.entity().add(SimTime::id()); let q = world .query::<(&SimConfig, &mut SimTime)>() .term_at(0) - .set_src_id(cfg) + .set_src(config) .term_at(1) - .set_src_id(game) + .set_src(game) .build(); // Ok (note that it.count() will be 0) q.run(|mut it| { while it.next() { - let sc = it.field::(0).unwrap(); - let mut st = it.field::(1).unwrap(); + let sc = it.field::(0); + let mut st = it.field_mut::(1); st[0].value += sc[0].sim_speed; // 0 because it's a single source element } }); @@ -2540,21 +2610,26 @@ q.each_iter(|it, index, (sc, st)| { st.value += sc.sim_speed; }); +HIDE: /* // Not ok: there is no entity to pass to first argument q.each_entity(|e, (sc, st)| { st.value += sc.sim_speed; }); +HIDE: */ ``` A source may also be specified by name: -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let config = world.entity_named("Config").add(SimConfig::id()); +HIDE: let game = world.entity_named("Game").add(SimTime::id()); let q = world .query::<(&SimConfig, &SimTime)>() .term_at(0) - .set_src_name("Cfg") + .set_src("Config") .term_at(1) - .set_src_name("Game") + .set_src("Game") .build(); ``` @@ -2652,23 +2727,24 @@ flecs::query<> q3 = world.query_builder()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // These three queries are the same: let q1 = world .query::<()>() - .with::() - .up_type::() + .with(Mass::id()) + .up_id(flecs::ChildOf::id()) .build(); let q2 = world .query::<()>() - .with::() + .with(Mass::id()) .up() // defaults to .up(flecs::ChildOf) .build(); let q3 = world .query::<()>() - .with::() + .with(Mass::id()) .parent() // shortcut for .up(flecs::ChildOf) .build(); ``` @@ -2718,7 +2794,8 @@ flecs::query<> q2 = world.query_builder()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Register an inheritable component 'Mass' world .component::() @@ -2727,14 +2804,14 @@ flecs::query<> q2 = world.query_builder() // These two queries are the same: let q1 = world .query::<()>() - .with::() + .with(Mass::id()) .self_() - .up_type::() + .up_id(flecs::IsA::id()) .build(); let q2 = world .query::<()>() - .with::() // defaults to .self().up(flecs::IsA) + .with(Mass::id()) // defaults to .self().up(flecs::IsA) .build(); ``` @@ -2789,22 +2866,23 @@ flecs::query<> q = world.query_builder()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Register an inheritable component 'Mass' world .component::() .add_trait::<(flecs::OnInstantiate, flecs::Inherit)>(); -let base = world.entity().add::(); +let base = world.entity().add(Mass::id()); -let parent = world.entity().is_a_id(base); // inherits Mass +let parent = world.entity().is_a(base); // inherits Mass -let child = world.entity().child_of_id(parent); +let child = world.entity().child_of(parent); // Matches 'child', because parent inherits Mass from prefab let q = world .query::<()>() - .with::() + .with(Mass::id()) .up() // traverses ChildOf upwards .build(); ``` @@ -2939,14 +3017,15 @@ flecs::query<> q = world.query_builder() The following example shows a query that matches an inherited component: -```rust +```rust test +HIDE: let world = World::new(); // Register inheritable 'Position' component world .component::() .add_trait::<(flecs::OnInstantiate, flecs::Inherit)>(); - let base = world.entity().add::(); - let inst = world.entity().is_a_id(base); // short for .add_id((flecs::IsA::ID, base)); + let base = world.entity().add(Position::id()); + let inst = world.entity().is_a(base); // short for .add((flecs::IsA::ID, base)); // The following two queries are the same: let q1 = world.new_query::<&Position>(); @@ -2961,9 +3040,10 @@ The following example shows a query that matches an inherited component: The following example shows a query that matches a component from a parent: -```rust -let parent = world.entity().add::(); -let child = world.entity().child_of_id(parent); // short for .add_id((flecs::ChildOf::ID, base)); +```rust test +HIDE: let world = World::new(); +let parent = world.entity().add(Position::id()); +let child = world.entity().child_of(parent); // short for .add((flecs::ChildOf::ID, base)); let q = world .query::<&Position>() @@ -2973,13 +3053,14 @@ let q = world The following example shows a query that traverses a custom relationship: -```rust +```rust test +HIDE: let world = World::new(); // Create a new traversable relationship -let contained_by = world.entity().add::(); +let contained_by = world.entity().add(flecs::Traversable::id()); -let parent = world.entity().add::(); +let parent = world.entity().add(Position::id()); -let child = world.entity().add_id((contained_by, parent)); +let child = world.entity().add((contained_by, parent)); let q = world .query::<&Position>() @@ -3204,27 +3285,29 @@ q.iter().set_var("Location", earth).each([]{ Query variables can be specified by specifying a name with a `$` prefix: -```rust +```rust test +HIDE: let world = World::new(); let q = world .query::<()>() - .with::() - .with::() - .set_second_name("$Location") - .with::() - .set_src_name("$Location") + .with(SpaceShip::id()) + .with(DockedTo::id()) + .set_second("$Location") + .with(Planet::id()) + .set_src("$Location") .build(); ``` Alternatively, variables can also be specified using the `var` method: -```rust +```rust test +HIDE: let world = World::new(); let q = world .query::<()>() - .with::() - .with::() + .with(SpaceShip::id()) + .with(DockedTo::id()) .second() .set_var("$Location") - .with::() + .with(Planet::id()) .src() .set_var("$Location") .build(); @@ -3232,9 +3315,20 @@ let q = world An application can constrain the results of the query by setting the variable before starting iteration: -```rust +```rust test +HIDE: let world = World::new(); let earth = world.entity(); -let location_var = q.find_var("$Location").unwrap(); +HIDE:let q = world +HIDE: .query::<()>() +HIDE: .with(SpaceShip::id()) +HIDE: .with(DockedTo::id()) +HIDE: .second() +HIDE: .set_var("$Location") +HIDE: .with(Planet::id()) +HIDE: .src() +HIDE: .set_var("$Location") +HIDE: .build(); +let location_var = q.find_var("Location").unwrap(); q.iterable().set_var(location_var, earth).each(|it| { // iterate as usual @@ -3243,10 +3337,21 @@ q.iterable().set_var(location_var, earth).each(|it| { Alternatively the variable name can be provided to `set_var` directly: -```rust +```rust test +HIDE: let world = World::new(); let earth = world.entity(); - -q.iterable().set_var_expr("$Location", earth).each(|it| { +HIDE:let q = world +HIDE: .query::<()>() +HIDE: .with(SpaceShip::id()) +HIDE: .with(DockedTo::id()) +HIDE: .second() +HIDE: .set_var("$Location") +HIDE: .with(Planet::id()) +HIDE: .src() +HIDE: .set_var("$Location") +HIDE: .build(); + +q.iterable().set_var_expr("Location", earth).each(|it| { // iterate as usual }); ``` @@ -3322,7 +3427,8 @@ flecs::query<> q = world.query()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Rust API does not support member value queries until reflection is implemented. This is the Meta addon. ``` @@ -3481,7 +3587,8 @@ q_read.run([](flecs::iter& it) { The following example shows how the change detection API is used in C++: -```rust +```rust test +HIDE: let world = World::new(); // Query used for change detection. let q_read = world.query::<&Position>() .detect_changes() @@ -3653,7 +3760,8 @@ auto q = world.query_builder() The following example shows how to use sorted queries in Rust: -```rust +```rust test +HIDE: let world = World::new(); // Use readonly term for component used for sorting let q = world .query::<(&Depth, &Position)>() @@ -3665,12 +3773,13 @@ let q = world Queries may specify a component id if the component is not known at compile time: -```rust +```rust test +HIDE: let world = World::new(); let depth_id = world.component::(); let q = world .query::<&Position>() - .with_id(depth_id) + .with(depth_id) .set_in() .order_by_id(depth_id, |e1, d1: *const c_void, e2, d2: *const c_void| { let d1 = unsafe { &*(d1 as *const Depth) }; @@ -3682,7 +3791,8 @@ let q = world Queries may specify zero for component id to sort on entity ids: -```rust +```rust test +HIDE: let world = World::new(); let q = world .query::<&Position>() .order_by_id(0, |e1, _d1: *const c_void, e2, _d2: *const c_void| { @@ -3850,19 +3960,22 @@ This section for Rust is unfinished. For code examples, see the group_by example The following example shows how grouping can be used to group entities that are in the same game region. -```rust +```rust test +HIDE: let world = World::new(); // see example in examples folder under query/group_by ``` When no `group_by` functions, it will default to an internal function with the same behavior as the previous example. An example: -```rust +```rust test +HIDE: let world = World::new(); // see example in examples folder under query/group_by ``` To iterate entities in a single group, use the `set_group` function: -```rust +```rust test +HIDE: let world = World::new(); // see example in examples folder under query/group_by ``` @@ -3925,17 +4038,18 @@ flecs::query q = world.query(); The following example shows a query that uses component inheritance to match entities: -```rust +```rust test +HIDE: let world = World::new(); #[derive(Component)] struct Unit; let unit = world.component::(); -let melee_unit = world.entity().is_a::(); -let ranged_unit = world.entity().is_a::(); +let melee_unit = world.entity().is_a(Unit::id()); +let ranged_unit = world.entity().is_a(Unit::id()); -let unit_01 = world.entity().add_id(melee_unit); -let unit_02 = world.entity().add_id(ranged_unit); +let unit_01 = world.entity().add(melee_unit); +let unit_02 = world.entity().add(ranged_unit); // Matches entities with Unit, MeleeUnit and RangedUnit let q = world.query::<&Unit>(); @@ -4076,22 +4190,23 @@ flecs::query<> q = world.query_builder() The following example shows a query that uses transitivity to match entities that are located in New York: -```rust +```rust test +HIDE: let world = World::new(); // Create LocatedIn relationship with transitive property #[derive(Component)] struct LocatedIn; -world.component::().add::(); +world.component::().add(flecs::Transitive::id()); let new_york = world.entity(); -let manhattan = world.entity().add_first::(new_york); -let central_park = world.entity().add_first::(manhattan); -let bob = world.entity().add_first::(central_park); +let manhattan = world.entity().add((LocatedIn::id(), new_york)); +let central_park = world.entity().add((LocatedIn::id(), manhattan)); +let bob = world.entity().add((LocatedIn::id(), central_park)); // Matches ManHattan, CentralPark, Bob let q = world .query::<()>() - .with_first::(new_york) + .with((LocatedIn::id(), new_york)) .build(); // Iterate as usual @@ -4099,26 +4214,30 @@ let q = world Queries for transitive relationships can be compared with variables. This query returns all locations an entity is in: -```rust +```rust test +HIDE: let world = World::new(); // Matches: // - ManHattan (Place = NewYork) // - CentralPark (Place = ManHattan, NewYork) // - Bob (Place = CentralPark, ManHattan, NewYork) let q = world .query::<()>() - .with::() - .set_second_name("$Place") + .with(LocatedIn::id()) + .set_second("$Place") .build(); ``` Variables can be used to constrain the results of a transitive query. The following query returns locations an entity is in that are a city: -```rust +```rust test +HIDE: let world = World::new(); #[derive(Component)] struct City; +HIDE: let new_york = world.entity(); + // Add City property to NewYork -new_york.add::(); +new_york.add(City::id()); // Matches: // - ManHattan (Place = NewYork) @@ -4127,10 +4246,10 @@ new_york.add::(); let q = world .query::<()>() - .with::() - .set_second_name("$Place") - .with::() - .set_src_name("$Place") + .with(LocatedIn::id()) + .set_second("$Place") + .with(City::id()) + .set_src("$Place") .build(); ``` @@ -4206,14 +4325,15 @@ flecs::query<> q = world.query_builder() The following example shows a query that uses the `IsA` reflexive relationship: -```rust +```rust test +HIDE: let world = World::new(); let tree = world.entity(); -let oak = world.entity().is_a_id(tree); +let oak = world.entity().is_a(tree); // Matches Tree, Oak let q = world .query::<()>() -.with_first::(tree) +.with((flecs::IsA::id(), tree)) .build(); // Iterate as usual diff --git a/docs/Quickstart.md b/docs/Quickstart.md index 1098ead460..1c54d669d2 100644 --- a/docs/Quickstart.md +++ b/docs/Quickstart.md @@ -182,7 +182,7 @@ using World world = World.Create();
  • Rust -```rust +```rust test let world = World::new(); // Do the ECS stuff @@ -243,7 +243,8 @@ e.IsAlive(); // false!
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let e = world.entity(); e.is_alive(); // true! @@ -297,11 +298,14 @@ Console.WriteLine($"Entity name: {e.Name()}");
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let world = World::new(); let e = world.entity_named("bob"); println!("Entity name: {}", e.name()); ``` +
  • Clojure @@ -337,8 +341,13 @@ Entity e = world.Lookup("Bob");
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: world.entity_named("bob"); +//if you are sure it exists let e = world.lookup("bob"); +//else use +let e = world.try_lookup("bob"); ```
  • Clojure @@ -436,12 +445,19 @@ e.Remove();
  • Rust -```rust +```rust test +//notice the Default trait impl +#[derive(Default, Component)] +pub struct Velocity { + pub x: f32, + pub y: f32, +} + +HIDE: let world = World::new(); let e = world.entity(); -// Add a component. This creates the component in the ECS storage, but does not -// assign it with a value. -e.add::(); +// Add a component. This creates the component in the ECS storage, and defaults it. This requires the Default trait impl +e.add(Velocity::id()); // Set the value for the Position & Velocity components. A component will be // added if the entity doesn't have it yet. @@ -454,7 +470,7 @@ e.get::<&Position>(|p| { }); // Remove component -e.remove::(); +e.remove(Position::id()); ```
  • Clojure @@ -523,13 +539,14 @@ posE.Add();
  • Rust Rust applications can use the `world::entity_from` function. -```rust +```rust test +HIDE: let world = World::new(); let pos_e = world.entity_from::(); println!("Name: {}", pos_e.name()); // outputs 'Name: Position' // It's possible to add components like you would for any entity -pos_e.add::(); +pos_e.add(Serializable::id()); ```
  • Clojure @@ -583,7 +600,8 @@ Console.WriteLine($"Component size: {c.size}");
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let pos_e = world.entity_from::(); pos_e.get::<&flecs::Component>(|c| { @@ -677,27 +695,28 @@ e.Has(Enemy); // false!
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Option 1: create Tag as empty struct #[derive(Component)] struct Enemy; // Create entity, add Enemy tag -let e = world.entity().add::(); -e.has::(); // true! +let e = world.entity().add(Enemy); +e.has(Enemy::id()); // true! -e.remove::(); -e.has::(); // false! +e.remove(Enemy::id()); +e.has(Enemy::id()); // false! // Option 2: create Tag as entity let enemy = world.entity(); // Create entity, add Enemy tag -let e = world.entity().add_id(enemy); -e.has_id(enemy); // true! +let e = world.entity().add(enemy); +e.has(enemy); // true! -e.remove_id(enemy); -e.has_id(enemy); // false! +e.remove(enemy); +e.has(enemy); // false! ```
  • Clojure @@ -780,7 +799,8 @@ Bob.Has(Alice); // false!
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Create Likes relationship as empty type (tag) #[derive(Component)] struct Likes; @@ -789,12 +809,12 @@ struct Likes; let bob = world.entity(); let alice = world.entity(); -bob.add_first::(alice); // bob likes alice -alice.add_first::(bob); // alice likes bob -bob.has_first::(alice); // true! +bob.add((Likes::id(), alice.id())); // bob likes alice +alice.add((Likes::id(), bob.id())); // alice likes bob +bob.has((Likes::id(), alice.id())); // true! -bob.remove_first::(alice); -bob.has_first::(alice); // false! +bob.remove((Likes::id(), alice.id())); +bob.has((Likes::id(), alice.id())); // false! ```
  • Clojure @@ -839,8 +859,10 @@ Id id = world.Pair(bob);
  • Rust -```rust -let id = world.id_first::(bob); +```rust test +HIDE: let world = World::new(); +HIDE: let bob = world.entity(); +let id = world.id_from((Likes::id(), bob.id())); ```
  • Clojure @@ -886,8 +908,9 @@ if (id.IsPair())
  • Rust -```rust -let id = world.id_from::<(Likes, Apples)>(); +```rust test +HIDE: let world = World::new(); +let id = world.id_view_from((Likes::id(), Apples::id())); if id.is_pair() { let relationship = id.first_id(); let target = id.second_id(); @@ -949,15 +972,20 @@ Bob.Has(Grows, Pears); // true!
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let eats = world.entity(); +HIDE: let apples = world.entity(); +HIDE: let pears = world.entity(); +HIDE: let grows = world.entity(); let bob = world.entity(); -bob.add_id((eats, apples)); -bob.add_id((eats, pears)); -bob.add_id((grows, pears)); +bob.add((eats, apples)); +bob.add((eats, pears)); +bob.add((grows, pears)); -bob.has_id((eats, apples)); // true! -bob.has_id((eats, pears)); // true! -bob.has_id((grows, pears)); // true! +bob.has((eats, apples)); // true! +bob.has((eats, pears)); // true! +bob.has((grows, pears)); // true! ```
  • Clojure @@ -996,9 +1024,11 @@ Entity o = Alice.Target(); // Returns Bob
  • Rust -```rust -let alice = world.entity().add_first::(bob); -let o = alice.target::(0); // Returns bob +```rust test +HIDE: let world = World::new(); +HIDE: let bob = world.entity(); +let alice = world.entity().add((Likes,bob)); +let o = alice.target(Likes,0); // Returns bob ```
  • Clojure @@ -1051,9 +1081,10 @@ parent.Destruct();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let parent = world.entity(); -let child = world.entity().child_of_id(parent); +let child = world.entity().child_of(parent); // Deleting the parent also deletes its children parent.destruct(); @@ -1125,9 +1156,10 @@ parent.Lookup("child"); // returns child
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let parent = world.entity_named("parent"); -let child = world.entity_named("child").child_of_id(parent); +let child = world.entity_named("child").child_of(parent); println!("Child path: {}", child.path().unwrap()); // output: 'parent::child' @@ -1197,7 +1229,8 @@ q.Each((ref Position p, ref Position pParent) =>
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let q = world .query::<(&Position, &mut Position)>() .term_at(1) @@ -1268,8 +1301,10 @@ Console.WriteLine(e.Type().Str()); // output: 'Position,Velocity'
  • Rust -```rust -let e = world.entity().add::().add::(); +```rust test +HIDE: let world = World::new(); +// types added via add or defaulted. If no default trait is implemented, use set instead +let e = world.entity().add(Position::id()).add(Velocity::id()); println!("Components: {}", e.archetype().to_string().unwrap()); // output: 'Position,Velocity' ``` @@ -1324,7 +1359,9 @@ e.Each((Id id) =>
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let e = world.entity().add(Position::id()).add(Velocity::id()); e.each_component(|id| { if id == world.component_id::() { // Found Position component! @@ -1386,13 +1423,14 @@ ref readonly Gravity g = ref world.Get();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Set singleton component -world.set(Gravity { x: 10, y: 20 }); +world.set(Gravity { value: 9.8 }); // Get singleton component world.get::<&Gravity>(|g| { - println!("Gravity: {}, {}", g.x, g.y); + println!("Gravity: {}", g.value); }); ```
  • @@ -1441,13 +1479,14 @@ ref readonly Gravity g = ref gravE.Get();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let grav_e = world.entity_from::(); -grav_e.set(Gravity { x: 10, y: 20 }); +grav_e.set(Gravity { value: 9.8 }); grav_e.get::<&Gravity>(|g| { - println!("Gravity: {}, {}", g.x, g.y); + println!("Gravity: {}", g.value); }); ```
  • @@ -1498,7 +1537,8 @@ world.QueryBuilder().Build();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world .query::<(&Velocity, &Gravity)>() .build(); @@ -1611,7 +1651,8 @@ q.Iter((Iter it, Field p) =>
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // For simple queries the world::each function can be used world.each::<(&mut Position, &Velocity)>(|(p, v)| { // EntityView argument is optional, use each_entity to get it @@ -1619,10 +1660,11 @@ world.each::<(&mut Position, &Velocity)>(|(p, v)| { p.y += v.y; }); -// More complex queries can first be created, then iterated +// More complex queries can first be created, then iterated +HIDE: let parent = world.entity(); let q = world .query::<&Position>() - .with_id((flecs::ChildOf::ID, parent)) + .with((flecs::ChildOf::ID, parent)) .build(); // Option 1: the each() callback iterates over each entity @@ -1633,7 +1675,7 @@ q.each_entity(|e, p| { // Option 2: the run() callback offers more control over the iteration q.run(|mut it| { while it.next() { - let p = it.field::(0).unwrap(); + let p = it.field::(0); for i in it.iter() { println!("{}: ({}, {})", it.entity(i).name(), p[i].x, p[i].y); @@ -1713,11 +1755,12 @@ using Query q = world.QueryBuilder()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let q = world .query::<()>() - .with::<(flecs::ChildOf, flecs::Wildcard)>() - .with::() + .with((flecs::ChildOf, flecs::Wildcard)) + .with(Position::id()) .set_oper(OperKind::Not) .build(); @@ -1807,7 +1850,8 @@ moveSys.Run();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Use each_entity() function that iterates each individual entity let move_sys = world .system::<(&mut Position, &Velocity)>() @@ -1882,9 +1926,11 @@ moveSys.Entity.Destruct();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let move_sys = world.system::<(&mut Position, &Velocity)>().each(|(p, v)| {}); println!("System: {}", move_sys.name()); -move_sys.add::(); +move_sys.add(flecs::pipeline::OnUpdate); move_sys.destruct(); ```
  • @@ -1945,7 +1991,7 @@ Ecs.OnStore
  • Rust -```rust +```rust test flecs::pipeline::OnLoad; flecs::pipeline::PostLoad; flecs::pipeline::PreUpdate; @@ -2008,20 +2054,21 @@ world.Progress();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world .system_named::<(&mut Position, &Velocity)>("Move") - .kind::() + .kind(flecs::pipeline::OnUpdate) .each(|(p, v)| {}); world .system_named::<(&mut Position, &Transform)>("Transform") - .kind::() + .kind(flecs::pipeline::PostUpdate) .each(|(p, t)| {}); world .system_named::<(&Transform, &mut Mesh)>("Render") - .kind::() + .kind(flecs::pipeline::OnStore) .each(|(t, m)| {}); world.progress(); @@ -2089,9 +2136,11 @@ moveSys.Remove(Ecs.PostUpdate);
  • Rust -```rust -move_sys.add::(); -move_sys.remove::(); +```rust test +HIDE: let world = World::new(); +HIDE: let move_sys = world.system::<(&mut Position, &Velocity)>().each(|(p, v)| {}); +move_sys.add(flecs::pipeline::OnUpdate); +move_sys.remove(flecs::pipeline::PostUpdate); ```
  • Clojure @@ -2160,7 +2209,8 @@ e.Set(new(20, 30)); // Invokes the observer
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world .observer_named::("OnSetPosition") .each(|(p, v)| {}); // Callback code is same as system @@ -2264,7 +2314,8 @@ world.Import();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); #[derive(Component)] struct MyModule; diff --git a/docs/Relationships.md b/docs/Relationships.md index ac62b989a2..d13accae47 100644 --- a/docs/Relationships.md +++ b/docs/Relationships.md @@ -76,16 +76,17 @@ Bob.Remove(Likes, Alice);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let likes = world.entity(); let bob = world.entity(); let alice = world.entity(); // bob likes alice -bob.add_id((likes, alice)); +bob.add((likes, alice)); // bob likes alice no more -bob.remove_id((likes, alice)); +bob.remove((likes, alice)); ```
  • @@ -148,18 +149,20 @@ Bob.Has(Eats, Pears); // true
  • Rust -```rust +```rust test +HIDE: let world = World::new(); + let bob = world.entity(); let eats = world.entity(); let apples = world.entity(); let pears = world.entity(); -bob.add_id((eats, apples)); -bob.add_id((eats, pears)); +bob.add((eats, apples)); +bob.add((eats, pears)); -bob.has_id((eats, apples)); // true -bob.has_id((eats, pears)); // true +bob.has((eats, apples)); // true +bob.has((eats, pears)); // true ```
  • @@ -231,7 +234,12 @@ Query q = world.QueryBuilder()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let eats = world.entity(); +HIDE: let apples = world.entity(); +HIDE: world.component_named::("Eats"); +HIDE: world.component_named::("Apples"); // Find all entities that eat apples let q = world.query::<()>().expr("(Eats, Apples)").build(); @@ -239,11 +247,11 @@ let q = world.query::<()>().expr("(Eats, Apples)").build(); let q = world.query::<()>().expr("(Eats, *)").build(); // With the query builder API: -let q = world.query::<()>().with_id((eats, apples)).build(); +let q = world.query::<()>().with((eats, apples)).build(); // Or when using pair types, when both relationship & target are compile time types, they can be represented as a tuple: -let q = world.new_query::<&(Eats, Apples)>(); +let q = world.query::<()>().with((Eats::id(), Apples::id())).build(); ```
  • @@ -282,8 +290,12 @@ Bob.Has(Eats, Apples);
  • Rust -```rust -bob.has_id((eats, apples)); +```rust test +HIDE: let world = World::new(); +HIDE: let bob = world.entity(); +HIDE: let eats = world.entity(); +HIDE: let apples = world.entity(); +bob.has((eats, apples)); ```
  • @@ -317,8 +329,11 @@ Bob.Has(Eats, Ecs.Wildcard);
  • Rust -```rust -bob.has_id((eats, flecs::Wildcard::ID)); +```rust test +HIDE: let world = World::new(); +HIDE: let bob = world.entity(); +HIDE: let eats = world.entity(); +bob.has((eats, flecs::Wildcard)); ```
  • @@ -352,14 +367,18 @@ Entity parent = Bob.Parent();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let bob = world.entity(); let parent = bob.parent(); ```
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let bob = world.entity(); let parent = bob.parent(); ``` @@ -394,8 +413,11 @@ Entity food = Bob.Target(Eats);
  • Rust -```rust -let food = bob.target_id(eats, 0); // first target +```rust test +HIDE: let world = World::new(); +HIDE: let bob = world.entity(); +HIDE: let eats = world.entity(); +let food = bob.target(eats, 0); // first target ```
  • @@ -439,9 +461,12 @@ while ((food = Bob.Target(Eats, index++)) != 0)
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let bob = world.entity(); +HIDE: let eats = world.entity(); let mut index = 0; -while bob.target_id(eats, index).is_some() { +while bob.target(eats, index).is_some() { index += 1; } ``` @@ -477,8 +502,10 @@ Entity parent = Bob.TargetFor(Ecs.ChildOf);
  • Rust -```rust -let parent = bob.target_for::(flecs::ChildOf::ID); +```rust test +HIDE: let world = World::new(); +HIDE: let bob = world.entity(); +let parent = bob.target_for(flecs::ChildOf, Position::id()); ```
  • @@ -531,7 +558,9 @@ Bob.Each((Id id) =>
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let bob = world.entity(); bob.each_component(|id| { if id.is_pair() { let first = id.first_id(); @@ -593,10 +622,13 @@ world.FilterBuilder()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let eats = world.entity(); +HIDE: let apples = world.entity(); world .query::<()>() - .with_id((eats, apples)) + .with((eats, apples)) .build() .each_entity(|e, _| { // Iterate as usual @@ -661,13 +693,15 @@ world.FilterBuilder()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let eats = world.entity(); world .query::<()>() - .with_id((eats, flecs::Wildcard::ID)) + .with((eats, flecs::Wildcard)) .build() .each_iter(|it, i, _| { - let food = it.pair(0).unwrap().second_id(); // Apples, ... + let food = it.pair(0).second_id(); // Apples, ... let e = it.entity(i); // Iterate as usual }); @@ -716,7 +750,9 @@ parent.Children((Entity child) =>
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let parent = world.entity(); parent.each_child(|child| { // ... }); @@ -850,7 +886,8 @@ e.Add(Ecs.ChildOf, world.Id());
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Empty types (types without members) are letmatically interpreted as tags #[derive(Component)] @@ -859,6 +896,11 @@ struct Begin; #[derive(Component)] struct End; +#[derive(Component)] +pub struct Eats { + amount: u32, +} + // Tags let likes = world.entity(); let apples = world.entity(); @@ -866,7 +908,7 @@ let apples = world.entity(); let e = world.entity(); // Both likes and Apples are tags, so (likes, Apples) is a tag -e.add_id((likes, apples)); +e.add((likes, apples)); // Eats is a type and Apples is a tag, so (Eats, Apples) has type Eats e.set_pair::(Eats { amount: 1 }); @@ -877,8 +919,8 @@ e.set_pair::(Position { x: 100.0, y: 20.0 }); // Same for End // ChildOf has the Tag property, so even though Position is a type, the pair // does not assume the Position type -e.add_id((flecs::ChildOf::ID, world.component_id::())); -e.add::<(flecs::ChildOf, Position)>(); +e.add((flecs::ChildOf, world.component_id::())); +e.add((flecs::ChildOf, Position::id())); ```
  • @@ -952,7 +994,8 @@ e.Set(third, new(5, 6));
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let e = world.entity(); let first = world.entity(); @@ -1036,18 +1079,20 @@ q.Iter((Iter it) =>
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let likes = world.entity(); let q = world .query::<()>() - .with_id((likes, flecs::Wildcard::ID)) + .with((likes, flecs::Wildcard)) .build(); q.each_iter(|it, i, _| { println!( "entity {} has relationship {} {}", it.entity(i), - it.pair(0).unwrap().first_id().name(), - it.pair(0).unwrap().second_id().name() + it.pair(0).first_id().name(), + it.pair(0).second_id().name() ); }); ``` @@ -1085,7 +1130,9 @@ Query q = world.QueryBuilder().Expr("(Likes, *)").Build();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: world.entity_named("likes"); let q = world.query::<()>().expr("(likes, *)").build(); ``` @@ -1178,7 +1225,8 @@ bob.Each(Eats, (Entity obj) =>
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // bob eats apples and pears let bob = world.entity(); @@ -1186,16 +1234,16 @@ let eats = world.entity(); let apples = world.entity(); let pears = world.entity(); -bob.add_id((eats, apples)); -bob.add_id((eats, pears)); +bob.add((eats, apples)); +bob.add((eats, pears)); // Find all (Eats, *) relationships in bob's type -bob.each_pair(eats, flecs::Wildcard::ID, |id| { +bob.each_pair(eats, flecs::Wildcard, |id| { println!("bob eats {}", id.second_id().name()); }); // For target wildcard pairs, each_target_id() can be used: -bob.each_target_id(eats, |entity| { +bob.each_target(eats, |entity| { println!("bob eats {}", entity.name()); }); ``` @@ -1241,11 +1289,12 @@ Apple.Add(Ecs.IsA, Fruit);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let apple = world.entity(); let fruit = world.entity(); -apple.add_id((flecs::IsA::ID, fruit)); +apple.add((flecs::IsA::ID, fruit)); ```
  • @@ -1272,8 +1321,11 @@ Apple.IsA(Fruit);
  • Rust -```rust -apple.is_a_id(fruit); +```rust test +HIDE: let world = World::new(); +HIDE: let apple = world.entity(); +HIDE: let fruit = world.entity(); +apple.is_a(fruit); ```
  • @@ -1312,9 +1364,11 @@ GrannySmith.Add(Ecs.IsA, Apple);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let apple = world.entity(); let granny_smith = world.entity(); -granny_smith.add_id((flecs::IsA::ID, apple)); +granny_smith.add((flecs::IsA::ID, apple)); ```
  • @@ -1369,7 +1423,11 @@ Entity Frigate = world.Entity()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); + +world.component::().add_trait::<(flecs::OnInstantiate, flecs::Inherit)>(); + let spaceship = world .entity() .set(MaxSpeed { value: 100 }) @@ -1377,7 +1435,7 @@ let spaceship = world let frigate = world .entity() - .is_a_id(spaceship) // shorthand for .add(flecs::IsA, Spaceship) + .is_a(spaceship) // shorthand for .add(flecs::IsA, Spaceship) .set(Defense { value: 75 }); ``` @@ -1418,9 +1476,14 @@ v.Value == 100; // true
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: world.component::().add_trait::<(flecs::OnInstantiate, flecs::Inherit)>(); +HIDE: world.component::().add_trait::<(flecs::OnInstantiate, flecs::Inherit)>(); +HIDE: let spaceship = world.entity().set(MaxSpeed { value: 100 }).set(Defense { value: 50 }); +HIDE: let frigate = world.entity().is_a(spaceship).set(Defense { value: 75 }); // Obtain the inherited component from Spaceship -let is_100 = frigate.map::<&mut MaxSpeed, _>(|v| { +let is_100 = frigate.get::<&MaxSpeed>(|v| { v.value == 100 // True }); ``` @@ -1461,9 +1524,14 @@ v.Value == 75; // true
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: world.component::().add_trait::<(flecs::OnInstantiate, flecs::Inherit)>(); +HIDE: world.component::().add_trait::<(flecs::OnInstantiate, flecs::Inherit)>(); +HIDE: let spaceship = world.entity().set(MaxSpeed { value: 100 }).set(Defense { value: 50 }); +HIDE: let frigate = world.entity().is_a(spaceship).set(Defense { value: 75 }); // Obtain the overridden component from Frigate -let is_75 = frigate.map::<&mut Defense, _>(|v| { +let is_75 = frigate.get::<&mut Defense>(|v| { v.value == 75 // True }); ``` @@ -1529,16 +1597,21 @@ d.Value == 75; // true
  • Rust -```rust -let fast_frigate = world.entity().is_a_id(frigate).set(MaxSpeed { value: 200 }); +```rust test +HIDE: let world = World::new(); +HIDE: world.component::().add_trait::<(flecs::OnInstantiate, flecs::Inherit)>(); +HIDE: world.component::().add_trait::<(flecs::OnInstantiate, flecs::Inherit)>(); +HIDE: let spaceship = world.entity().set(MaxSpeed { value: 100 }).set(Defense { value: 50 }); +HIDE: let frigate = world.entity().is_a(spaceship).set(Defense { value: 75 }); +let fast_frigate = world.entity().is_a(frigate).set(MaxSpeed { value: 200 }); // Obtain the overridden component from FastFrigate -let is_200 = fast_frigate.map::<&mut MaxSpeed, _>(|v| { +let is_200 = fast_frigate.get::<&mut MaxSpeed>(|v| { v.value == 200 // True }); // Obtain the inherited component from Frigate -let is_75 = fast_frigate.map::<&mut Defense, _>(|v| { +let is_75 = fast_frigate.get::<&Defense>(|v| { v.value == 75 // True }); ``` @@ -1586,10 +1659,11 @@ Cockpit.Add(Ecs.ChildOf, Spaceship);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let spaceship = world.entity(); let cockpit = world.entity(); -cockpit.add_id((flecs::ChildOf::ID, spaceship)); +cockpit.add((flecs::ChildOf, spaceship)); ```
  • @@ -1616,8 +1690,11 @@ Cockpit.ChildOf(Spaceship);
  • Rust -```rust -cockpit.child_of_id(spaceship); +```rust test +HIDE: let world = World::new(); +HIDE: let cockpit = world.entity(); +HIDE: let spaceship = world.entity(); +cockpit.child_of(spaceship); ```
  • @@ -1679,12 +1756,13 @@ child == parent.Lookup("Child"); // true
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let parent = world.entity_named("Parent"); -let child = world.entity_named("Child").child_of_id(parent); +let child = world.entity_named("Child").child_of(parent); -child == world.lookup("Parent::Child"); // true -child == parent.lookup("Child"); // true +assert!(child == world.lookup("Parent::Child")); // true +assert!(child == parent.lookup("Child")); // true ```
  • @@ -1751,19 +1829,20 @@ childB.Has(Ecs.ChildOf, parent); // true
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let parent = world.entity(); -let prev = world.set_scope_id(parent); +let prev = world.set_scope(parent); let child_a = world.entity(); let child_b = world.entity(); // Restore the previous scope -world.set_scope_id(prev); +world.set_scope(prev); -child_a.has_id((flecs::ChildOf::ID, parent)); // true -child_b.has_id((flecs::ChildOf::ID, parent)); // true +child_a.has((flecs::ChildOf, parent)); // true +child_b.has((flecs::ChildOf, parent)); // true ```
  • @@ -1803,12 +1882,14 @@ Entity parent = world.Entity().Scope(() => <
  • Rust -```rust -let parent = world.entity().run_in_scope(|| { +```rust test +HIDE: let world = World::new(); +let parent = world.entity(); +parent.run_in_scope(|| { let child_a = world.entity(); let child_b = world.entity(); - child_a.has_id((flecs::ChildOf::ID, parent)); // true - child_b.has_id((flecs::ChildOf::ID, parent)); // true + child_a.has((flecs::ChildOf, parent)); // true + child_b.has((flecs::ChildOf, parent)); // true }); ``` diff --git a/docs/Systems.md b/docs/Systems.md index a57e8b2f39..a4ecf75667 100644 --- a/docs/Systems.md +++ b/docs/Systems.md @@ -67,7 +67,8 @@ System sys = world.System("Move")
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // System declaration world .system_named::<(&mut Position, &Velocity)>("Move") @@ -105,8 +106,17 @@ sys.Run();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let sys = world +HIDE: .system_named::<(&mut Position, &Velocity)>("Move") +HIDE: .each(|(p, v)| { +HIDE: p.x += v.x; +HIDE: p.y += v.y; +HIDE: }); +HIDE: /* let sys = ...; +HIDE: */ sys.run(); ```
  • @@ -138,7 +148,8 @@ world.Progress();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); let world = World::new(); world.progress(); ``` @@ -173,10 +184,11 @@ System sys = world.System("Move")
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world .system_named::<(&mut Position, &Velocity)>("Move") - .kind_id(0) + .kind(0) .each(|(p, v)| { /* ... */ }); ```
  • @@ -301,9 +313,12 @@ The `Iter` function can be invoked multiple times per frame, once for each match
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // `.each_entity` if you need the associated entity. +HIDE: let q = world.query::<(&Position, &Velocity)>().build(); + // Query iteration (each) q.each(|(p, v)| { /* ... */ }); @@ -312,16 +327,15 @@ world .system_named::<(&mut Position, &Velocity)>("Move") .each(|(p, v)| { /* ... */ }); ``` -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let q = world.query::<(&Position, &Velocity)>().build(); // Query iteration (run) q.run(|mut it| { while it.next() { - let mut p = it - .field::(0) - .expect("query term changed and not at the same index anymore"); - let v = it - .field::(1) - .expect("query term changed and not at the same index anymore"); + let mut p = it.field_mut::(0); + let v = it.field::(1); + for i in it.iter() { p[i].x += v[i].x; p[i].y += v[i].y; @@ -334,12 +348,8 @@ world .system_named::<(&mut Position, &Velocity)>("Move") .run(|mut it| { while it.next() { - let mut p = it - .field::(0) - .expect("query term changed and not at the same index anymore"); - let v = it - .field::(1) - .expect("query term changed and not at the same index anymore"); + let mut p = it.field_mut::(0); + let v = it.field::(1); for i in it.iter() { p[i].x += v[i].x; p[i].y += v[i].y; @@ -347,23 +357,30 @@ world } }); ``` -```rust -// Query iteration (run_iter) -q.run_iter(|it, (p, v)| { - for i in it.iter() { - p[i].x += v[i].x; - p[i].y += v[i].y; - } -}); +```rust test +HIDE: let world = World::new(); + +HIDE: let q = world.query::<(&mut Position, &Velocity)>().build(); +// Query iteration (run_each_iter) + q.run_each_iter(|mut it| { + while it.next() { + it.each(); + } + }, |it,i,(p, v)| { + p.x += v.x; + p.y += v.y; + }); -// System iteration (run_iter) +// System iteration (run_each_iter) world .system_named::<(&mut Position, &Velocity)>("Move") - .run_iter(|it, (p, v)| { - for i in it.iter() { - p[i].x += v[i].x; - p[i].y += v[i].y; + .run_each_iter(|mut it| { + while it.next() { + it.each(); } + }, |it,i,(p, v)| { + p.x += v.x; + p.y += v.y; }); ``` @@ -438,22 +455,14 @@ world.System("Move")
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world .system_named::<(&mut Position, &Velocity)>("Move") .each_iter(|it, i, (p, v)| { p.x += v.x * it.delta_time(); p.y += v.y * it.delta_time(); }); - -world - .system_named::<(&mut Position, &Velocity)>("Move") - .run_iter(|it, (p, v)| { - for i in it.iter() { - p[i].x += v[i].x * it.delta_time(); - p[i].y += v[i].y * it.delta_time(); - } - }); ```
  • @@ -482,7 +491,9 @@ world.Progress(deltaTime);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let delta_time = 0.016; world.progress_time(delta_time); ```
  • @@ -512,7 +523,8 @@ world.Progress();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world.progress(); ```
  • @@ -578,7 +590,8 @@ world.progress();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world.system_named::<()>("PrintTime").run(|mut it| { while it.next() { println!("Time: {}", it.delta_time()); @@ -647,14 +660,16 @@ world.System("PrintTime")
  • Rust -```rust +```rust test +HIDE: let world = World::new(); + +world.component::().add_trait::(); + world .system_named::<&Game>("PrintTime") - .term_at(0) - .singleton() - .kind::() - .run_iter(|it, game| { - println!("Time: {}", game[0].time); + .kind(flecs::pipeline::OnUpdate::id()) + .each(|game| { + println!("Time: {}", game.time); }); ```
  • @@ -706,11 +721,12 @@ world.System("Move")
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // System is created with (DependsOn, OnUpdate) world .system_named::<(&mut Position, &Velocity)>("Move") - .kind::() + .kind(flecs::pipeline::OnUpdate::id()) .each(|(p, v)| { // ... }); @@ -850,16 +866,17 @@ world.Pipeline()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world .pipeline() - .with::() - .with::() - .cascade_type::() - .without::() - .up_type::() - .without::() - .up_type::() + .with(flecs::system::System::id()) + .with(flecs::pipeline::Phase::id()) + .cascade_id(flecs::DependsOn::id()) + .without(flecs::Disabled::id()) + .up_id(flecs::DependsOn::id()) + .without(flecs::Disabled::id()) + .up_id(flecs::ChildOf::id()) .build(); ``` @@ -938,21 +955,22 @@ world.Progress();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // Create custom pipeline let pipeline = world .pipeline() - .with::() - .with::() // or `.with_id(foo) if an id` + .with(flecs::system::System::id()) + .with(Foo::id()) // or `.with(foo) if an id` .build(); // Configure the world to use the custom pipeline -world.set_pipeline_id(pipeline); +world.set_pipeline(pipeline); // Create system world .system_named::<(&mut Position, &Velocity)>("Move") - .kind::() // or `.kind_id(foo) if an id` + .kind(Foo::id()) .each(|(p, v)| { p.x += v.x; p.y += v.y; @@ -992,8 +1010,14 @@ move.Entity.Add(foo);
  • Rust -```rust -move_sys.add::(); +```rust test +HIDE: let world = World::new(); +HIDE: let move_sys = world +HIDE: .system_named::<(&mut Position, &Velocity)>("Move").run(|mut it| { +HIDE: while it.next() { +HIDE: } +HIDE: }); +move_sys.add(Foo::id()); ``` @@ -1031,7 +1055,12 @@ s.Entity.Enable();
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: let s = world.system_named::<(&mut Position, &Velocity)>("Move").each(|(p, v)| { +HIDE: p.x += v.x; +HIDE: p.y += v.y; +HIDE: }); // Disable system s.disable_self(); // Enable system @@ -1064,8 +1093,15 @@ s.Entity.Add(Ecs.Disabled);
  • Rust -```rust -sys.add::(); +```rust test +HIDE: let world = World::new(); +HIDE: let sys = world +HIDE: .system_named::<(&mut Position, &Velocity)>("Move") +HIDE: .each(|(p, v)| { +HIDE: p.x += v.x; +HIDE: p.y += v.y; +HIDE: }); +sys.add(flecs::Disabled::id()); ```
  • @@ -1157,9 +1193,10 @@ world.System()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // In the Rust API, use the write method to indicate commands could be inserted. -world.system::<&Position>().write::().each(|p| { +world.system::<&Position>().write(Transform::id()).each(|p| { // ... }); ``` @@ -1210,9 +1247,10 @@ world.System()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); // In the Rust API, use the read method to indicate a component is read using .get -world.system::<&Position>().read::().each(|p| { +world.system::<&Position>().read(Transform::id()).each(|p| { // ... }); ``` @@ -1271,7 +1309,8 @@ ecs.System("AssignPlate")
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world .system_named::<&Plate>("AssignPlate") .immediate(true) // disable readonly mode for this system @@ -1337,7 +1376,11 @@ void AssignPlate(ecs_iter_t *it) {
  • Rust -```rust +```rust test +HIDE: let world = World::new(); +HIDE: world +HIDE: .system_named::<&Plate>("AssignPlate") +HIDE: .immediate(true) // disable readonly mode for this system .run(|mut it| { while it.next() { // ECS operations ran here are visible after running the system @@ -1378,7 +1421,8 @@ world.SetThreads(4);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world.set_threads(4); ```
  • @@ -1421,8 +1465,9 @@ world.System()
  • Rust -```rust -world.system::<&Position>().multi_threaded().each(|p| { +```rust test +HIDE: let world = World::new(); +world.system::<&Position>().par_each(|p| { // ... }); ``` @@ -1459,7 +1504,8 @@ world.SetTaskThreads(4);
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world.set_task_threads(4); ```
  • @@ -1521,9 +1567,10 @@ world.System()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world.system::<&Position>() - .interval(1.0) // Run at 1Hz + .set_interval(1.0) // Run at 1Hz .each(|p| { // ... }); @@ -1577,10 +1624,11 @@ world.System()
  • Rust -```rust +```rust test +HIDE: let world = World::new(); world .system::<&Position>() - .rate(2) // Run every other frame + .set_rate(2) // Run every other frame .each(|p| { // ... }); @@ -1652,8 +1700,14 @@ world.System()
  • Rust -```rust -// Timer not yet implemented in Rust +```rust test +HIDE: let world = World::new(); + +let tick_source = world.timer().set_interval(1.0); + +world.system::<(&mut Position, &Velocity)>() +.set_tick_source(tick_source) +.each(|(p,v)| { /* ... */}); ```
  • @@ -1694,8 +1748,15 @@ tickSource.Start();
  • Rust -```rust -// Timer addon yet to be implemented in rust +```rust test +HIDE: let world = World::new(); +HIDE: let tick_source = world.timer().set_interval(1.0); + +// Pause timer +tick_source.stop(); + +// Resume timer +tick_source.start(); ```
  • @@ -1756,8 +1817,17 @@ TimerEntity eachHour = world.Timer()
  • Rust -```rust -// Timer not yet implemented in Rust +```rust test +HIDE: let world = World::new(); + +// tick at 1Hz +let each_second = world.timer().set_interval(1.0); + +// tick each minute +let each_minute = world.timer().set_rate_w_tick_source(60, each_second); + +// tick each hour +let each_hour = world.timer().set_rate_w_tick_source(60, each_minute); ```
  • @@ -1846,8 +1916,25 @@ System_ eachHour = world.System("EachHour")
  • Rust -```rust -// Timer not yet implemented in Rust +```rust test +HIDE: let world = World::new(); +let each_second = world.system_named::<()>("EachSecond") + .set_interval(1.0) + .run(|mut it| { + /* ... */ + }); +let each_minute = world.system_named::<()>("EachMinute") + .set_tick_source(each_second) + .set_rate(60) + .run(|mut it| { + /* ... */ + }); +let each_hour = world.system_named::<()>("EachHour") + .set_tick_source(each_minute) + .set_rate(60) + .run(|mut it| { + /* ... */ + }); ```