diff --git a/docs/FlecsQueryLanguage.md b/docs/FlecsQueryLanguage.md index abbeb9eed..df7a0c348 100644 --- a/docs/FlecsQueryLanguage.md +++ b/docs/FlecsQueryLanguage.md @@ -6,7 +6,7 @@ The Flecs Query Language is a string-based representation of queries. The query This manual is primarily focused on describing the query syntax. For more details on specific query feature, see the query manual. ## Example -```swift +```c // Match spaceship entities that are docked to a planet SpaceShip, (DockedTo, $planet), Planet($planet) ``` @@ -17,7 +17,7 @@ An expression in the Flecs Query Language consists of a list of comma separated ### Components The most basic kind of condition is "the entity must have this component". The following expression is an example of a query that matches all entities that have both `Position` and `Velocity`: -```swift +```c // Match entities that have Position and Velocity Position, Velocity ``` @@ -26,7 +26,7 @@ Note that this query matches all entities that _at least_ have the `Position` an ### Pairs The following expression is an example of a query that matches two pairs: -```swift +```c // Match entities that have (Likes, Bob) and (Eats, Apples) (Likes, Bob), (Eats, Apples) ``` @@ -37,7 +37,7 @@ Query operators change how a term is matched against entities. Only a single ope ### Not The `not` operator, specified with the `!` character, inverts the result of a term and makes it possible to match entities that _do not_ satisfy a condition. The following expression is an example of a query with a `not` operator: -```swift +```c // Match entities that have Position but not Velocity Position, !Velocity ``` @@ -45,7 +45,7 @@ Position, !Velocity ### Or The `or` operator, specified with the `||` character, makes it possible to chain together a list of terms of which at least one term must be true. The following expression is an example of a query with an `or` operator: -```swift +```c // Match entities that have Position and Velocity or Mass Position, Velocity || Mass ``` @@ -58,7 +58,7 @@ The `optional` operator, specified with the `?` character, optionally matches a The following expression is an example of a query with an `optional` operator: -```swift +```c // Match entities that have Position and optionally Velocity Position, ?Velocity ``` @@ -68,7 +68,7 @@ the `andfrom` operator allows a query to match a list of components that another The following expression is an example of a query with an `andfrom` operator: -```swift +```c // Match entities with Position and all components that MyType has Position, and|MyType ``` @@ -83,7 +83,7 @@ flecs::entity my_type = world.prefab("MyType") This would cause the above query to be equivalent to: -```swift +```c Position, Velocity, Mass ``` @@ -92,7 +92,7 @@ the `notfrom` operator allows a query to not match a list of components that ano The following expression is an example of a query with an `notfrom` operator: -```swift +```c // Match entities with Position and not any of the components that MyType has Position, not|MyType ``` @@ -107,7 +107,7 @@ flecs::entity my_type = world.prefab("MyType") This would cause the above query to be equivalent to: -```swift +```c Position, !Velocity, !Mass ``` @@ -116,7 +116,7 @@ the `orfrom` operator allows a query to match at least one of a list of componen The following expression is an example of a query with an `orfrom` operator: -```swift +```c // Match entities with Position and at least one of the components that MyType has Position, or|MyType ``` @@ -131,14 +131,14 @@ flecs::entity my_type = world.prefab("MyType") This would cause the above query to be equivalent to: -```swift +```c Position, Velocity || Mass ``` ## Wildcards Query expressions can use wildcards to match any or all instances of a matching component or pair. Wildcards may appear in all parts of a term. The following examples are all valid wildcard queries: -```swift +```c Position, (Likes, *) Position, (*, Dogs) Position, (*, *) @@ -150,7 +150,7 @@ Query results contain information about the exact component or pair that was mat ### Wildcard wildcard (*) The following expression is an example of a query that uses a wildcard: -```swift +```c // Match entities with a (Likes, *) pair // Return all matching pairs (Likes, *) @@ -160,7 +160,7 @@ The `*` wildcard returns all matching instances of the wildcard. If an entity ha If a query has multiple wildcards, each permutation of the matched results will be returned. The following expression is an example of a query that has multiple wildcards: -```swift +```c // Match entities with (Likes, *) and (Eats, *) pairs // Return all pair permutations (Likes, *), (Eats, *) @@ -176,7 +176,7 @@ If a single entity has `(Likes, Dogs)` and `(Likes, Cats)`, and has `(Eats, Pizz ### Any wildcard (_) The `any` (`_`) wildcard returns at most one result per wildcard. The following expression is an example of a query that uses an `any` wildcard: -```swift +```c // Match entities with a (Likes, *) pair // Return at most one result per entity (Likes, _) @@ -188,7 +188,7 @@ If an entity has both `(Likes, Dogs)` and `(Likes, Cats)`, the query will return If a query has multiple `any` wildcards, only a single result is returned. The following expression is an example of a query that has multiple wildcards: -```swift +```c // Match entities with (Likes, *) and (Eats, *) pairs // Return at most one result per entity (Likes, _), (Eats, _) @@ -201,7 +201,7 @@ If a single entity has `(Likes, Dogs)` and `(Likes, Cats)`, and has `(Eats, Pizz ## Variables Query variables constrain which values a wildcard can assume by ensuring that the value that was matched by a wildcard in one term is used in all other terms. The following expression is an example of a query that uses variables: -```swift +```c // Match all entities that eat what they like (Likes, $food), (Eats, $food) ``` @@ -212,7 +212,7 @@ If a single entity has `(Likes, Dogs)` and `(Likes, Pizza)`, and has `(Eats, Piz Note how this is a strict subset of the results that would be returned by the following query: -```swift +```c (Likes, *), (Eats, *) ``` @@ -228,11 +228,11 @@ Variables with names that that start with a `_` are treated as anonymous, and ar ## Source All query terms have a "source", which is the entity on which the term is matched. If no term source is specified, it defaults to the `$this` variable. The following expressions show the same query without and with explicit source: -```swift +```c // Implicit source Position, Velocity ``` -```swift +```c // Explicit source Position($this), Velocity($this) ``` @@ -241,11 +241,11 @@ Note how both terms have the same `$this` source. Using the same variable ensure The following expressions show how to use pair queries without and with explicit source: -```swift +```c // Implicit source (Likes, Dogs), (Eats, Salad) ``` -```swift +```c // Explicit source Likes($this, Dogs), Eats($this, Salad) ``` @@ -255,7 +255,7 @@ A single query can have terms that are matched on more than one source. The foll ### Static source A static source is a term that is always matched on an entity that is known at query creation time. A static source is specified by just using the name of the entity on which the component should be matched: -```swift +```c // Match TimeOfDay component on 'Game' entity TimeOfDay(Game) ``` @@ -264,51 +264,51 @@ TimeOfDay(Game) A singleton is a special case of a static source, where the source is the same as the component. The following expression shows an example of a singleton source: -```swift +```c TimeOfDay($) ``` This query is equivalent to: -```swift +```c TimeOfDay(TimeOfDay) ``` A singleton may also be used as the second element in a pair as shown in the next example: -```swift +```c TimeOfDay($this, $) ``` This query is equivalent to: -```swift +```c TimeOfDay($this, TimeOfDay) ``` ### Variable source A variable source is a variable that is used as term source. As mentioned already, when no source is specified, a term implicitly uses the builtin `$this` variable as source: -```swift +```c // Match entities with both Position and Velocity Position($this), Velocity($this) ``` A variable used as source may appear in a different location in other terms. For example, the following expression uses a variable to match all entities that have components with the `Serializable` component: -```swift +```c Serializable($component), $component($this) ``` The following example matches all spaceship entities that are docked to a planet: -```swift +```c SpaceShip($this), DockedTo($this, $planet), Planet($planet) ``` The following example matches all entities that are eating healthy, but do not like what they are eating: -```swift +```c Eats($this, $food), !Likes($this, $food), Healthy($food) ``` @@ -317,37 +317,37 @@ Query traversal makes it possible to match a component by traversing a relations The following expression shows an example of a query that matches a `Transform` component both on an entity and its parent: -```swift +```c Transform($this), Transform($this|up ChildOf) ``` The same query can be specified without the `$this` variable: -```swift +```c Transform, Transform(up ChildOf) ``` As `ChildOf` is the default traversal relationship, this query can be further shortened to: -```swift +```c Transform, Transform(up) ``` The `cascade` modifier is similar to `up` but returns results in breadth-first order. This is typically used in transform systems to ensure parents are transformed before children. The following expression shows an example with `cascade`: -```swift +```c Transform, Transform(cascade) ``` The `desc` modifier can be used in combination with `cascade` to return results in reverse order: -```swift +```c Transform, Transform(cascade|desc) ``` The `self` traversal modifier can be used in combination with `up` to first test if the entity itself has the component before traversing the hierarchy: -```swift +```c // First try matching Style on self, find on parent if not found Position, Style(self|up) ``` @@ -369,25 +369,25 @@ world.component().add(flecs::Traversable); When a query matches a component that is inherited from, a query will automatically traverse the `IsA` relationship downwards to find all subclasses. For example, if `MeleeUnit` has an `IsA` relationship to `Unit`, the following query matches entities with `Unit` and `MeleeUnit`: -```swift +```c Unit ``` To prevent queries from evaluating component inheritance, the `self` modifier can be added to the component: -```swift +```c Unit|self ``` For terms with an explicit source, the `self` modifier comes before the parentheses: -```swift +```c Unit|self($this) ``` When a query matches a relationship that has the `Transitive` trait, it will traverse the relationship up or down depending on which parts of the query are variable. To prevent a query from matching results transitively, add the `self` modifier to the second element of a pair: -```swift +```c LocatedIn($this, SanFrancisco|self) ``` @@ -398,50 +398,50 @@ This will only match entities that have `(LocatedIn, SanFrancisco)` and not, for ### Equality operators Equality operators allow queries to match variables with specific values or names. The following example shows a query that matches a variable against with a specific entity: -```swift +```c SpaceShip($this), $this == UssEnterprise || $this == Voyager ``` The `!=` operator can be used to negate a result: -```swift +```c SpaceShip($this), $this != UssEnterprise ``` Queries may also compare two variables: -```swift +```c PoweredBy($this, $source), $this != $source ``` When a string is used as operand, the operation will test if the name of the entity matches: -```swift +```c SpaceShip($this), $this == "UssEnterprise" ``` The `~=` operator can be used to do a fuzzy comparison, equivalent to the behavior of the `substr` function: -```swift +```c SpaceShip($this), $this ~= "Uss" ``` The result of `~=` can be negated by prefixing the expression with a `!`: -```swift +```c SpaceShip($this), $this ~= "!Uss" ``` When an equality operator is the first term that populates a variable, it will assign the variable: -```swift +```c $this == "UssEnterprise", SpaceShip($this) ``` ### Lookup variables Variables can be used as the starting point of a by-name lookup. This can be useful when matching hierarchies that have a well-defined structure. The following expression is an example of a query with a lookup variable: -```swift +```c // Match all spaceship entities where the cockpit has no power SpaceShip($this), !Powered($this.cockpit) ``` @@ -451,26 +451,26 @@ This query will look for an child entity named `cockpit` in the scope of the mat ### Member matching Queries can match against the values of component members if they are of the `ecs_entity_t` type. The following expression shows an example of how to match against a `direction` member in a `Movement` component: -```swift +```c Movement.direction($this, Left) ``` The same query with an implicit source: -```swift +```c (Movement.direction, Left) ``` A member expression can be used in combination with variables: -```swift +```c (Thrusters.left, $thruster), Active($thruster) ``` ### Dependent variables When a variable is used first in a term that is conditionally evaluated, any subsequent terms that use the variable will only be evaluated if the variable was set. This allows for the creation of simple branches within queries. The following expression shows an example of dependent variables: -```swift +```c // $animal and $food are set conditionally (Likes, $animal) || (Eats, $food), Friendly($animal), // Evaluated if (Likes, $animal) matched @@ -479,7 +479,7 @@ Healthy($food) // Evaluated if (Eats, $food) matched Dependent variables can also be created from optional terms: -```swift +```c // Planet($object) is only evaluated if (DockedTo, $object) // returned a result. SpaceShip, ?(Dockedto, $object), Planet($object) @@ -488,12 +488,12 @@ SpaceShip, ?(Dockedto, $object), Planet($object) ### Query scopes Query scopes can be used to apply an operator to the result of more than one term. Currently query scopes are only supported in combination with `not` operators. The following expressions show examples of query scopes: -```swift +```c // Match spaceships where none of the engines are healthy SpaceShip, !{ (Engine, $engine), Healthy($healthy) } ``` -```swift +```c // Match spaceships where all of the engines SpaceShip, !{ (Engine, $engine), !Healthy($healthy) } ``` diff --git a/docs/Queries.md b/docs/Queries.md index e6bed7fbb..a3d1f815d 100644 --- a/docs/Queries.md +++ b/docs/Queries.md @@ -145,10 +145,15 @@ However, to keep empty archetypes and non-empty archetypes in separate lists, ev To do this, a query should be created with the `EcsQueryMatchEmptyTables` flag, and the `ecs_delete_empty_tables` function should be called periodically. An example: +
+ +
+ This will cause queries to return empty archeypes (iterators with count set to 0) which is something the application code will have to handle correctly. ## Creating queries @@ -285,7 +308,7 @@ For more details on the syntax, see the Flecs Query Language manual. ## Iteration -This section describes the different ways queries can be iterated. The code examples use filters, but also apply to cached queries and rules. +This section describes the different ways queries can be iterated.
+### Variables Query variables represent the state of a query while it is being evaluated. The most common form of state is "the entity (or table) against which the query is evaluated". While a query is evaluating an entity or table, it has to store it somewhere. In flecs, that "somewhere" is a query variable. Consider this query example, written down with explicit term [sources](#source): @@ -2471,7 +2511,17 @@ SpaceShip($this), DockedTo($this, $Location) An application can set the `$this` variable or `$Location` variables, or both, before starting iteration to constrain the results returned by the query. This makes it possible to reuse a single query for multiple purposes, which provides better performance when compared to creating multiple queries. -The following sections show how to use queries in the different language bindings. The code examples use rules queries, which currently are the only queries that support using variables other than `$this`. +#### Lookup variables +Variables can be used as the starting point of a by-name lookup. This can be useful when matching hierarchies that have a well-defined structure. An example: + +```c +// Match all spaceship entities where the cockpit has no power +SpaceShip($this), !Powered($this.cockpit) +``` + +This query will look for an child entity named `cockpit` in the scope of the matched entity for `$this`, and use that entity to match with `Powered`. If no entity with the name `cockpit` is found, the term will evaluate to false. + +The following sections show how to use queries in the different language bindings.
+
+ +### Member Value Queries +Queries can match against the values of component members if they are of the `ecs_entity_t` type, and the component type is described with the reflection framework. Member value queries make it possible to query on values that can change rapidly without requiring structural changes in the ECS. The tradeoff is that other than with the regular, union and toggle storage options there are no acceleration structures to speed up query evaluation, which means that a query has to evaluate each instance of the component. + +The following sections show how to use queries in the different language bindings. + +
+ +
+ +Member value queries can be used in combination with wildcards: + +``` +Movement.value($htis, *) +``` + +Member value queries can be used in combination with variables: + +``` +Movement.value($htis, $direction), $direction != Left +``` + ### Change Detection Change detection makes it possible for applications to know whether data matching a query has changed. Changes are tracked at the table level, for each component in the table. While this is less granular than per entity tracking, the mechanism has minimal overhead, and can be used to skip entities in bulk. Change detection works by storing a list of counters on tracked tables, where each counter tracks changes for a component in the table. When a component in the table changes, the corresponding counter is increased. An additional counter is stored for changes that add or remove entities to the table. Queries with change detection store a copy of the list of counters for each table in the cache, and compare counters to detect changes. To reduce overhead, counters are only tracked for tables matched with queries that use change detection. The change detection feature cannot detect all changes. The following scenarios are detected by change detection: + - Anything that causes adding or removing a component, tag or pair - Deleting an entity - Setting a component value with `set` @@ -2598,6 +2740,7 @@ The change detection feature cannot detect all changes. The following scenarios - A change in tables matched by the query The following scenarios are not detected by change detection: + - Modifying a component obtained by `ensure` without calling `modified` - Modifying the value of a ref (`ecs_ref_t` or `flecs::ref`) without calling `modified` @@ -2710,6 +2853,10 @@ q_read.run([](flecs::iter& it) { }); ``` + + + + ### Sorting Sorted queries allow an application to specify a component that entities should be sorted on. Sorting is enabled by setting the `order_by` function in combination with the component to order on. Sorted queries sort the tables they match with when necessary. To determine whether a table needs to be sorted, sorted queries use [change detection](#change-detection). A query determines whether a sort operation is needed when an iterator is created for it. @@ -2833,6 +2980,10 @@ auto q = world.query_builder() .build(); ``` + + + + ### Grouping Grouping is the ability of queries to assign an id ("group id") to a set of tables. Grouped tables are iterated together, as they are stored together in the query cache. Additionally, groups in the query cache are sorted by group id, which guarantees that tables with a lower group id are iterated after tables with a higher group id. Grouping is only supported for cached queries. @@ -2853,7 +3004,7 @@ One example is that of an open game which is divided up into world cells. Even t Grouped iterators, when used in combination with a good group_by function are one of the fastest available mechanisms for finding entities in Flecs. The feature provides the iteration performance of having a cached query per group, but without the overhead of having to maintain multiple caches. Whether a group has ten or ten thousand tables does not matter, which makes the feature an enabler for games with large numbers of entities. -The following sections show how to use sorting in the different language bindings. The code examples use cached queries, which is the only kind of query for which change detection is supported. +The following sections show how to use grouping in the different language bindings. The code examples use cached queries, which is the only kind of query for which change detection is supported.
    @@ -2899,6 +3050,27 @@ uint64_t group_by_target( } ``` +When no value for `group_by_callback` is provided, it will default to an internal function with the same behavior as `group_by_target`. An example: + +```c +// Create query that groups entities that are in the same region +ecs_query(world, { + .terms = {{ Unit }}, + .group_by = Region +}); +``` + +To iterate entities in a single group, use the `ecs_iter_set_group` function: + +```c +ecs_iter_t it = ecs_query_iter(world, q); +ecs_iter_set_group(&it, Region_01); + +while (ecs_query_next(&it)) { + // iterate as usual +} +``` +
  • C++ @@ -2942,6 +3114,28 @@ flecs::query<> q = world.query_builder() .build(); ``` +When no `group_by` functions, it will default to an internal function with the same behavior as the previous example. An example: + +```c +// Create query that groups entities that are in the same region +flecs::query<> q = world.query_builder() + .with() + .group_by() + .build(); +``` + +To iterate entities in a single group, use the `set_group` function: + +```c +q.set_group(Region_01).each([](flecs::entity e) { + // iterate as usual +}); +``` + +
  • +
+
+ ### Component Inheritance Component inheritance allows for a query to match entities with a component and all subsets of that component, as defined by the `IsA` relationship. Component inheritance is enabled for all queries by default, for components where it applies. @@ -2949,13 +3143,13 @@ It is possible to prevent inheriting from a component from by adding the [Final] Inheritance relationships can, but are not required to mirror inheritance of the types used as long as it does not impact the layout of the type. Component inheritance is most often used with tags. -The following sections show how to use component inheritance in the different language bindings. The code examples use rules, which is the only kind of query for which component inheritance is currently supported. +The following sections show how to use component inheritance in the different language bindings.
  • C -The following example shows a rule that uses component inheritance to match entities: +The following example shows a query that uses component inheritance to match entities: ```c ecs_entity_t Unit = ecs_new(world); @@ -2976,7 +3170,7 @@ ecs_query_t *q = ecs_query(world, {
  • C++ -The following example shows a rule that uses component inheritance to match entities: +The following example shows a query that uses component inheritance to match entities: ```cpp flecs::entity Unit = ecs_new(world); @@ -2987,11 +3181,15 @@ flecs::entity unit_01 = world.entity().add(MeleeUnit); flecs::entity unit_02 = world.entity().add(RangedUnit); // Matches entities with Unit, MeleeUnit and RangedUnit -flecs::query r = world.query(); +flecs::query q = world.query(); // Iterate as usual ``` +
  • +
+
+ ### Transitive Relationships When a [transitive relationship](Relationships.md#transitive-relationships) is used by a query, a query will automatically look up or test against pairs that satisfy the transitive property. Transitivity is usually defined as: @@ -3003,13 +3201,15 @@ A relationship can be made transitive by adding the [transitive](Relationships.m An example of a builtin relationship that has the `Transitive` property is the `IsA` relationship. -The following sections show how to use transitive relationships in the different language bindings. The code examples use rules, which is the only kind of query for which transitive relationships are currently supported. +Transitive traversal can be disabled for a term with a transitive relationship by adding the `Self` flag to the second element of the pair. + +The following sections show how to use transitive relationships in the different language bindings.
  • C -The following example shows a rule that uses transitivity to match entities that are located in New York: +The following example shows a query that uses transitivity to match entities that are located in New York: ```c // Create LocatedIn relationship with transitive property @@ -3062,7 +3262,7 @@ ecs_query_t *q = ecs_query(world, {
  • C++ -The following example shows a rule that uses transitivity to match entities that are located in New York: +The following example shows a query that uses transitivity to match entities that are located in New York: ```cpp // Create LocatedIn relationship with transitive property @@ -3076,7 +3276,7 @@ flecs::entity CentralPark = world.entity().add(Manhattan); flecs::entity Bob = world.entity().add(CentralPark); // Matches ManHattan, CentralPark, Bob -flecs::query<> r = world.query_builder() +flecs::query<> q = world.query_builder() .with(NewYork) .build(); @@ -3090,7 +3290,7 @@ Queries for transitive relationships can be compared with variables. This query // - ManHattan (Place = NewYork) // - CentralPark (Place = ManHattan, NewYork) // - Bob (Place = CentralPark, ManHattan, NewYork) -flecs::query<> r = world.query_builder() +flecs::query<> q = world.query_builder() .with().second("$Place") .build(); ``` @@ -3107,7 +3307,7 @@ NewYork.add(City); // - ManHattan (Place = NewYork) // - CentralPark (Place = NewYork) // - Bob (Place = NewYork) -flecs::query<> r = world.query_builder() +flecs::query<> q = world.query_builder() .with().second("$Place") .with().src("$Place") .build(); @@ -3147,13 +3347,13 @@ When a query matches a [reflexive](Relationships.md#reflexive-property) relation For example, if relationship IsA (R) is reflexive, then a Tree (X) is a Tree (X). An example of a builtin relationship that has the `Reflexive` property is the `IsA` relationship. -The following sections show how to use transitive relationships in the different language bindings. The code examples use rules, which is the only kind of query for which transitive relationships are currently supported. +The following sections show how to use transitive relationships in the different language bindings.
    • C -The following example shows a rule that uses the `IsA` reflexive relationship: +The following example shows a query that uses the `IsA` reflexive relationship: ```c ecs_entity_t Tree = ecs_new(world); @@ -3168,14 +3368,14 @@ ecs_query_t *q = ecs_query(world, {
    • C++ -The following example shows a rule that uses the `IsA` reflexive relationship: +The following example shows a query that uses the `IsA` reflexive relationship: ```cpp flecs::entity Tree = world.entity(); flecs::entity Oak = world.entity().is_a(Tree); // Matches Tree, Oak -flecs::query<> r = world.query_builder() +flecs::query<> q = world.query_builder() .with(flecs::IsA, Tree) .build(); ``` diff --git a/include/flecs/addons/cpp/mixins/query/builder_i.hpp b/include/flecs/addons/cpp/mixins/query/builder_i.hpp index 98224d4f7..8f73a7259 100644 --- a/include/flecs/addons/cpp/mixins/query/builder_i.hpp +++ b/include/flecs/addons/cpp/mixins/query/builder_i.hpp @@ -26,7 +26,7 @@ struct query_builder_i : term_builder_i { return *this; } - Base& flags(ecs_flags32_t flags) { + Base& query_flags(ecs_flags32_t flags) { desc_->flags |= flags; return *this; } diff --git a/include/flecs/addons/cpp/mixins/term/builder_i.hpp b/include/flecs/addons/cpp/mixins/term/builder_i.hpp index cf2097485..8e4b4ddc7 100644 --- a/include/flecs/addons/cpp/mixins/term/builder_i.hpp +++ b/include/flecs/addons/cpp/mixins/term/builder_i.hpp @@ -25,14 +25,14 @@ struct term_ref_builder_i { /* The self flag indicates the term identifier itself is used */ Base& self() { - this->assert_term_id(); + this->assert_term_ref(); term_ref_->id |= flecs::Self; return *this; } /* Specify value of identifier by id */ Base& id(flecs::entity_t id) { - this->assert_term_id(); + this->assert_term_ref(); term_ref_->id = id; return *this; } @@ -46,14 +46,14 @@ struct term_ref_builder_i { * both id(entity_t) and id(const char*). */ Base& entity(flecs::entity_t entity) { - this->assert_term_id(); + this->assert_term_ref(); term_ref_->id = entity | flecs::IsEntity; return *this; } /* Specify value of identifier by name */ Base& name(const char *name) { - this->assert_term_id(); + this->assert_term_ref(); term_ref_->id |= flecs::IsEntity; term_ref_->name = const_cast(name); return *this; @@ -61,7 +61,7 @@ struct term_ref_builder_i { /* Specify identifier is a variable (resolved at query evaluation time) */ Base& var(const char *var_name) { - this->assert_term_id(); + this->assert_term_ref(); term_ref_->id |= flecs::IsVariable; term_ref_->name = const_cast(var_name); return *this; @@ -69,7 +69,7 @@ struct term_ref_builder_i { /* Override term id flags */ Base& flags(flecs::flags32_t flags) { - this->assert_term_id(); + this->assert_term_ref(); term_ref_->id = flags; return *this; } @@ -79,7 +79,7 @@ struct term_ref_builder_i { protected: virtual flecs::world_t* world_v() = 0; - void assert_term_id() { + void assert_term_ref() { ecs_assert(term_ref_ != NULL, ECS_INVALID_PARAMETER, "no active term (call .term() first)"); } @@ -216,7 +216,7 @@ struct term_builder_i : term_ref_builder_i { * traversing a relationship upwards. For example: substitute the identifier * with its parent by traversing the ChildOf relationship. */ Base& up(flecs::entity_t trav = 0) { - this->assert_term_id(); + this->assert_term_ref(); ecs_check(this->term_ref_ != &term_->first, ECS_INVALID_PARAMETER, "up traversal can only be applied to term source"); ecs_check(this->term_ref_ != &term_->second, ECS_INVALID_PARAMETER, @@ -237,7 +237,7 @@ struct term_builder_i : term_ref_builder_i { /* The cascade flag is like up, but returns results in breadth-first order. * Only supported for flecs::query */ Base& cascade(flecs::entity_t trav = 0) { - this->assert_term_id(); + this->assert_term_ref(); this->up(); this->term_ref_->id |= flecs::Cascade; if (trav) { @@ -253,7 +253,7 @@ struct term_builder_i : term_ref_builder_i { /* Use with cascade to iterate results in descending (bottom -> top) order */ Base& desc() { - this->assert_term_id(); + this->assert_term_ref(); this->term_ref_->id |= flecs::Desc; return *this; } @@ -265,7 +265,7 @@ struct term_builder_i : term_ref_builder_i { /* Specify relationship to traverse, and flags to indicate direction */ Base& trav(flecs::entity_t trav, flecs::flags32_t flags = 0) { - this->assert_term_id(); + this->assert_term_ref(); term_->trav = trav; this->term_ref_->id |= flags; return *this; diff --git a/test/cpp/src/QueryBuilder.cpp b/test/cpp/src/QueryBuilder.cpp index f5cdf2a1d..5e6a94e01 100644 --- a/test/cpp/src/QueryBuilder.cpp +++ b/test/cpp/src/QueryBuilder.cpp @@ -4739,7 +4739,7 @@ void QueryBuilder_unresolved_by_name(void) { flecs::world ecs; auto q = ecs.query_builder() - .flags(EcsQueryAllowUnresolvedByName) + .query_flags(EcsQueryAllowUnresolvedByName) .expr("$this == Foo") .cache_kind(cache_kind) .build();