Properly link flecs library
This commit is contained in:
5
engine/libs/flecs/examples/cpp/queries/basics/.gitignore
vendored
Normal file
5
engine/libs/flecs/examples/cpp/queries/basics/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
.bake_cache
|
||||
.DS_Store
|
||||
.vscode
|
||||
gcov
|
||||
bin
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef BASICS_H
|
||||
#define BASICS_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
#include "basics/bake_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef BASICS_BAKE_CONFIG_H
|
||||
#define BASICS_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
|
||||
#endif
|
||||
|
||||
12
engine/libs/flecs/examples/cpp/queries/basics/project.json
Normal file
12
engine/libs/flecs/examples/cpp/queries/basics/project.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"id": "basics",
|
||||
"type": "application",
|
||||
"value": {
|
||||
"author": "Jane Doe",
|
||||
"description": "A simple hello world flecs application",
|
||||
"use": [
|
||||
"flecs"
|
||||
],
|
||||
"language": "c++"
|
||||
}
|
||||
}
|
||||
70
engine/libs/flecs/examples/cpp/queries/basics/src/main.cpp
Normal file
70
engine/libs/flecs/examples/cpp/queries/basics/src/main.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#include <basics.h>
|
||||
#include <iostream>
|
||||
|
||||
struct Position {
|
||||
double x, y;
|
||||
};
|
||||
|
||||
struct Velocity {
|
||||
double x, y;
|
||||
};
|
||||
|
||||
int main(int, char *[]) {
|
||||
flecs::world ecs;
|
||||
|
||||
// Create a query for Position, Velocity. Queries are the fastest way to
|
||||
// iterate entities as they cache results.
|
||||
flecs::query<Position, const Velocity> q = ecs.query<Position, const Velocity>();
|
||||
|
||||
// Create a few test entities for a Position, Velocity query
|
||||
ecs.entity("e1")
|
||||
.set<Position>({10, 20})
|
||||
.set<Velocity>({1, 2});
|
||||
|
||||
ecs.entity("e2")
|
||||
.set<Position>({10, 20})
|
||||
.set<Velocity>({3, 4});
|
||||
|
||||
// This entity will not match as it does not have Position, Velocity
|
||||
ecs.entity("e3")
|
||||
.set<Position>({10, 20});
|
||||
|
||||
|
||||
// The next lines show the different ways in which a query can be iterated.
|
||||
// Note how the 'const' qualifier matches the query template arguments.
|
||||
|
||||
// The each() function iterates each entity individually and accepts an
|
||||
// entity argument plus arguments for each query component:
|
||||
q.each([](flecs::entity e, Position& p, const Velocity& v) {
|
||||
p.x += v.x;
|
||||
p.y += v.y;
|
||||
std::cout << e.name() << ": {" << p.x << ", " << p.y << "}\n";
|
||||
});
|
||||
|
||||
// You can omit the flecs::entity argument if it's not needed:
|
||||
q.each([](Position& p, const Velocity& v) {
|
||||
p.x += v.x;
|
||||
p.y += v.y;
|
||||
std::cout << "{" << p.x << ", " << p.y << "}\n";
|
||||
});
|
||||
|
||||
// Each also accepts flecs::iter + index (for the iterated entity) arguemnts
|
||||
// currently being iterated. A flecs::iter has lots of information on what
|
||||
// is being iterated, which is demonstrated in the "iter" example.
|
||||
q.each([](flecs::iter& it, size_t i, Position& p, const Velocity& v) {
|
||||
p.x += v.x;
|
||||
p.y += v.y;
|
||||
std::cout << it.entity(i).name() << ": {" << p.x << ", " << p.y << "}\n";
|
||||
});
|
||||
|
||||
// Iter is a bit more verbose, but allows for more control over how entities
|
||||
// are iterated as it provides multiple entities in the same callback.
|
||||
q.iter([](flecs::iter& it, Position *p, const Velocity *v) {
|
||||
for (auto i : it) {
|
||||
p[i].x += v[i].x;
|
||||
p[i].y += v[i].y;
|
||||
std::cout << it.entity(i).name() <<
|
||||
": {" << p[i].x << ", " << p[i].y << "}\n";
|
||||
}
|
||||
});
|
||||
}
|
||||
5
engine/libs/flecs/examples/cpp/queries/change_tracking/.gitignore
vendored
Normal file
5
engine/libs/flecs/examples/cpp/queries/change_tracking/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
.bake_cache
|
||||
.DS_Store
|
||||
.vscode
|
||||
gcov
|
||||
bin
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef CHANGE_TRACKING_H
|
||||
#define CHANGE_TRACKING_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
#include "change_tracking/bake_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef CHANGE_TRACKING_BAKE_CONFIG_H
|
||||
#define CHANGE_TRACKING_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"id": "change_tracking",
|
||||
"type": "application",
|
||||
"value": {
|
||||
"use": [
|
||||
"flecs"
|
||||
],
|
||||
"language": "c++"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
#include <change_tracking.h>
|
||||
#include <iostream>
|
||||
|
||||
// Queries have a builtin mechanism for tracking changes per matched table. This
|
||||
// is a cheap way of eliminating redundant work, as many entities can be skipped
|
||||
// with a single check.
|
||||
//
|
||||
// This example shows how to use change tracking in combination with a few other
|
||||
// techniques, like using prefabs to store a single dirty state for multiple
|
||||
// entities and instanced queries.
|
||||
|
||||
struct Dirty {
|
||||
bool value;
|
||||
};
|
||||
|
||||
struct Position {
|
||||
double x, y;
|
||||
};
|
||||
|
||||
int main(int, char *[]) {
|
||||
flecs::world ecs;
|
||||
|
||||
// Create a query that just reads a component. We'll use this query for
|
||||
// change tracking. Change tracking for a query is automatically enabled
|
||||
// when query::changed() is called.
|
||||
// Each query has its own private dirty state which is reset only when the
|
||||
// query is iterated.
|
||||
flecs::query<const Position> q_read = ecs.query<const Position>();
|
||||
|
||||
// Create a query that writes the component based on a Dirty state.
|
||||
flecs::query<const Dirty, Position> q_write =
|
||||
ecs.query_builder<const Dirty, Position>()
|
||||
.term_at(1).up() // Only match Dirty from prefab
|
||||
.instanced() // Instanced iteration is faster (see example)
|
||||
.build();
|
||||
|
||||
// Create two prefabs with a Dirty component. We can use this to share a
|
||||
// single Dirty value for all entities in a table.
|
||||
flecs::entity p1 = ecs.prefab("p1").set<Dirty>({false});
|
||||
flecs::entity p2 = ecs.prefab("p2").set<Dirty>({true});
|
||||
|
||||
// Create instances of p1 and p2. Because the entities have different
|
||||
// prefabs, they end up in different tables.
|
||||
ecs.entity("e1").is_a(p1)
|
||||
.set<Position>({10, 20});
|
||||
|
||||
ecs.entity("e2").is_a(p1)
|
||||
.set<Position>({30, 40});
|
||||
|
||||
ecs.entity("e3").is_a(p2)
|
||||
.set<Position>({40, 50});
|
||||
|
||||
ecs.entity("e4").is_a(p2)
|
||||
.set<Position>({60, 70});
|
||||
|
||||
// We can use the changed() function on the query to check if any of the
|
||||
// tables it is matched with has changed. Since this is the first time that
|
||||
// we check this and the query is matched with the tables we just created,
|
||||
// the function will return true.
|
||||
std::cout << "q_read.changed(): " << q_read.changed() << "\n";
|
||||
|
||||
// The changed state will remain true until we have iterated each table.
|
||||
q_read.iter([](flecs::iter& it) {
|
||||
// With the it.changed() function we can check if the table we're
|
||||
// currently iterating has changed since last iteration.
|
||||
// Because this is the first time the query is iterated, all tables
|
||||
// will show up as changed.
|
||||
std::cout << "it.changed() for table [" << it.type().str() << "]: "
|
||||
<< it.changed() << "\n";
|
||||
});
|
||||
|
||||
// Now that we have iterated all tables, the dirty state is reset.
|
||||
std::cout << "q_read.changed(): " << q_read.changed() << "\n\n";
|
||||
|
||||
// Iterate the write query. Because the Position term is InOut (default)
|
||||
// iterating the query will write to the dirty state of iterated tables.
|
||||
q_write.iter([](flecs::iter& it, const Dirty *dirty, Position *p) {
|
||||
std::cout << "iterate table [" << it.type().str() << "]\n";
|
||||
|
||||
// Because we enforced that Dirty is a shared component, we can check
|
||||
// a single value for the entire table.
|
||||
if (!dirty->value) {
|
||||
// If the dirty flag is false, skip the table. This way the table's
|
||||
// dirty state is not updated by the query.
|
||||
it.skip();
|
||||
std::cout << "it.skip() for table [" << it.type().str() << "]\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// For all other tables the dirty state will be set.
|
||||
for (auto i : it) {
|
||||
p[i].x ++;
|
||||
p[i].y ++;
|
||||
}
|
||||
});
|
||||
|
||||
// One of the tables has changed, so q_read.changed() will return true
|
||||
std::cout << "\nq_read.changed(): " << q_read.changed() << "\n";
|
||||
|
||||
// When we iterate the read query, we'll see that one table has changed.
|
||||
q_read.iter([](flecs::iter& it) {
|
||||
std::cout << "it.changed() for table [" << it.type().str() << "]: "
|
||||
<< it.changed() << "\n";
|
||||
});
|
||||
|
||||
// Output:
|
||||
// q_read.changed(): 1
|
||||
// it.changed() for table [Position, (Identifier,Name), (IsA,p1)]: 1
|
||||
// it.changed() for table [Position, (Identifier,Name), (IsA,p2)]: 1
|
||||
// q_read.changed(): 0
|
||||
//
|
||||
// iterate table [Position, (Identifier,Name), (IsA,p1)]
|
||||
// it.skip() for table [Position, (Identifier,Name), (IsA,p1)]
|
||||
// iterate table [Position, (Identifier,Name), (IsA,p2)]
|
||||
//
|
||||
// q_read.changed(): 1
|
||||
// it.changed() for table [Position, (Identifier,Name), (IsA,p1)]: 0
|
||||
// it.changed() for table [Position, (Identifier,Name), (IsA,p2)]: 1
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef FIND_ENTITY_H
|
||||
#define FIND_ENTITY_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
#include "find_entity/bake_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef FIND_ENTITY_BAKE_CONFIG_H
|
||||
#define FIND_ENTITY_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "find_entity",
|
||||
"type": "application",
|
||||
"value": {
|
||||
"use": [
|
||||
"flecs"
|
||||
],
|
||||
"language": "c++",
|
||||
"public": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#include <find_entity.h>
|
||||
#include <iostream>
|
||||
|
||||
struct Position {
|
||||
int x, y;
|
||||
};
|
||||
|
||||
int main() {
|
||||
flecs::world ecs;
|
||||
|
||||
ecs.entity("e1").set<Position>({10, 20});
|
||||
ecs.entity("e2").set<Position>({20, 30});
|
||||
|
||||
// Create a simple query for component Position
|
||||
flecs::query<Position> q = ecs.query<Position>();
|
||||
|
||||
// Find the entity for which Position.x is 20
|
||||
flecs::entity e = q.find([](Position& p) {
|
||||
return p.x == 20;
|
||||
});
|
||||
|
||||
if (e) {
|
||||
std::cout << "Found entity " << e.path() << std::endl;
|
||||
} else {
|
||||
std::cout << "No entity found" << std::endl;
|
||||
}
|
||||
|
||||
// Output
|
||||
// Found entity ::e2
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef GROUP_BY_H
|
||||
#define GROUP_BY_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
#include "group_by/bake_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef GROUP_BY_BAKE_CONFIG_H
|
||||
#define GROUP_BY_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
|
||||
#endif
|
||||
|
||||
11
engine/libs/flecs/examples/cpp/queries/group_by/project.json
Normal file
11
engine/libs/flecs/examples/cpp/queries/group_by/project.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "group_by",
|
||||
"type": "application",
|
||||
"value": {
|
||||
"use": [
|
||||
"flecs"
|
||||
],
|
||||
"language": "c++",
|
||||
"public": false
|
||||
}
|
||||
}
|
||||
113
engine/libs/flecs/examples/cpp/queries/group_by/src/main.cpp
Normal file
113
engine/libs/flecs/examples/cpp/queries/group_by/src/main.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
#include <group_by.h>
|
||||
#include <iostream>
|
||||
|
||||
// Group by is a feature of cached queries that allows applications to assign a
|
||||
// group id to each matched table. Tables that are assigned the same group id
|
||||
// are stored together in "groups". This ensures that when a query is iterated,
|
||||
// tables that share a group are iterated together.
|
||||
//
|
||||
// Groups in the cache are ordered by group id, which ensures that tables with
|
||||
// lower ids are iterated before table with higher ids. This is the same
|
||||
// mechanism that is used by the cascade feature, which groups tables by depth
|
||||
// in a relationship hierarchy.
|
||||
//
|
||||
// This makes groups a more efficient, though less granular mechanism for
|
||||
// ordering entities. Order is maintained at the group level, which means that
|
||||
// once a group is created, tables can get added and removed to the group
|
||||
// with is an O(1) operation.
|
||||
//
|
||||
// Groups can also be used as an efficient filtering mechanism. See the
|
||||
// set_group example for more details.
|
||||
|
||||
struct Position {
|
||||
double x, y;
|
||||
};
|
||||
|
||||
// Dummy tag to put entities in different tables
|
||||
struct Tag { };
|
||||
|
||||
// Create a relationship to use for the group_by function. Tables will
|
||||
// be assigned the relationship target as group id
|
||||
struct Group { };
|
||||
|
||||
// Targets for the relationship, which will be used as group ids.
|
||||
struct First { };
|
||||
struct Second { };
|
||||
struct Third { };
|
||||
|
||||
int main() {
|
||||
flecs::world ecs;
|
||||
|
||||
// Register components in order so that id for First is lower than Third
|
||||
ecs.component<First>();
|
||||
ecs.component<Second>();
|
||||
ecs.component<Third>();
|
||||
|
||||
// Grouped query
|
||||
flecs::query<Position> q = ecs.query_builder<Position>()
|
||||
.group_by<Group>()
|
||||
.build();
|
||||
|
||||
// Create entities in 6 different tables with 3 group ids
|
||||
ecs.entity().add<Group, Third>()
|
||||
.set<Position>({1, 1});
|
||||
ecs.entity().add<Group, Second>()
|
||||
.set<Position>({2, 2});
|
||||
ecs.entity().add<Group, First>()
|
||||
.set<Position>({3, 3});
|
||||
|
||||
ecs.entity().add<Group, Third>()
|
||||
.set<Position>({4, 4})
|
||||
.add<Tag>();
|
||||
ecs.entity().add<Group, Second>()
|
||||
.set<Position>({5, 5})
|
||||
.add<Tag>();
|
||||
ecs.entity().add<Group, First>()
|
||||
.set<Position>({6, 6})
|
||||
.add<Tag>();
|
||||
|
||||
// The query cache now looks like this:
|
||||
// - group First:
|
||||
// - table [Position, (Group, First)]
|
||||
// - table [Postion, Tag, (Group, First)]
|
||||
//
|
||||
// - group Second:
|
||||
// - table [Position, (Group, Second)]
|
||||
// - table [Postion, Tag, (Group, Second)]
|
||||
//
|
||||
// - group Third:
|
||||
// - table [Position, (Group, Third)]
|
||||
// - table [Postion, Tag, (Group, Third)]
|
||||
//
|
||||
|
||||
q.iter([&](flecs::iter& it, Position *p) {
|
||||
flecs::entity group = ecs.entity(it.group_id());
|
||||
std::cout << " - group " << group.path() << ": table ["
|
||||
<< it.table().str() << "]\n";
|
||||
|
||||
for (auto i : it) {
|
||||
std::cout << " {" << p[i].x << ", " << p[i].y << "}\n";
|
||||
}
|
||||
|
||||
std::cout << "\n";
|
||||
});
|
||||
|
||||
// Output:
|
||||
// - group ::First: table [Position, (Group,First)]
|
||||
// {3, 3}
|
||||
//
|
||||
// - group ::First: table [Position, Tag, (Group,First)]
|
||||
// {6, 6}
|
||||
//
|
||||
// - group ::Second: table [Position, (Group,Second)]
|
||||
// {2, 2}
|
||||
//
|
||||
// - group ::Second: table [Position, Tag, (Group,Second)]
|
||||
// {5, 5}
|
||||
//
|
||||
// - group ::Third: table [Position, (Group,Third)]
|
||||
// {1, 1}
|
||||
//
|
||||
// - group ::Third: table [Position, Tag, (Group,Third)]
|
||||
// {4, 4}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef GROUP_BY_CALLBACKS_H
|
||||
#define GROUP_BY_CALLBACKS_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
#include "group_by_callbacks/bake_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef GROUP_BY_CALLBACKS_BAKE_CONFIG_H
|
||||
#define GROUP_BY_CALLBACKS_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "group_by_callbacks",
|
||||
"type": "application",
|
||||
"value": {
|
||||
"use": [
|
||||
"flecs"
|
||||
],
|
||||
"public": false,
|
||||
"language": "c++"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
#include <group_by_callbacks.h>
|
||||
#include <iostream>
|
||||
|
||||
// This example shows how the on_group_create and on_group_delete callbacks can
|
||||
// be used to get notified when a new group is registered for a query. These
|
||||
// callbacks make it possible to associate and manage user data attached to
|
||||
// groups.
|
||||
|
||||
struct Position {
|
||||
double x, y;
|
||||
};
|
||||
|
||||
// Custom type to associate with group
|
||||
struct group_ctx {
|
||||
int32_t counter;
|
||||
};
|
||||
|
||||
int group_counter = 0;
|
||||
|
||||
// Dummy tag to put entities in different tables
|
||||
struct Tag { };
|
||||
|
||||
// Create a relationship to use for the group_by function. Tables will
|
||||
// be assigned the relationship target as group id
|
||||
struct Group { };
|
||||
|
||||
// Targets for the relationship, which will be used as group ids.
|
||||
struct First { };
|
||||
struct Second { };
|
||||
struct Third { };
|
||||
|
||||
int main() {
|
||||
flecs::world ecs;
|
||||
|
||||
// Register components in order so that id for First is lower than Third
|
||||
ecs.component<First>();
|
||||
ecs.component<Second>();
|
||||
ecs.component<Third>();
|
||||
|
||||
// Grouped query
|
||||
flecs::query<Position> q = ecs.query_builder<Position>()
|
||||
.group_by<Group>()
|
||||
|
||||
// Callback invoked when a new group is created
|
||||
.on_group_create([](flecs::world_t *world,
|
||||
uint64_t id, // id of the group that was created
|
||||
void *group_by_arg) // group_by_ctx parameter in ecs_query_desc_t struct
|
||||
{
|
||||
(void)group_by_arg; // silence unused warning
|
||||
flecs::world w(world);
|
||||
std::cout << "Group " << w.entity(id).name() << " created\n";
|
||||
|
||||
// Return data that will be associated with the group
|
||||
group_ctx *ctx = new group_ctx;
|
||||
ctx->counter = ++ group_counter;
|
||||
return static_cast<void*>(ctx); // Cast to make sure function type matches
|
||||
})
|
||||
|
||||
// Callback invoked when a group is deleted
|
||||
.on_group_delete([](flecs::world_t *world,
|
||||
uint64_t id, // id of the group that was deleted
|
||||
void *ctx, // group context
|
||||
void *group_by_arg) // group_by_ctx parameter in ecs_query_desc_t struct
|
||||
{
|
||||
(void)group_by_arg; // silence unused warning
|
||||
flecs::world w(world);
|
||||
std::cout << "Group " << w.entity(id).name() << " deleted\n";
|
||||
|
||||
// Free data associated with group
|
||||
delete static_cast<group_ctx*>(ctx);
|
||||
})
|
||||
.build();
|
||||
|
||||
// Create entities in 6 different tables with 3 group ids
|
||||
ecs.entity().add<Group, Third>()
|
||||
.set<Position>({1, 1});
|
||||
ecs.entity().add<Group, Second>()
|
||||
.set<Position>({2, 2});
|
||||
ecs.entity().add<Group, First>()
|
||||
.set<Position>({3, 3});
|
||||
|
||||
ecs.entity().add<Group, Third>()
|
||||
.set<Position>({4, 4})
|
||||
.add<Tag>();
|
||||
ecs.entity().add<Group, Second>()
|
||||
.set<Position>({5, 5})
|
||||
.add<Tag>();
|
||||
ecs.entity().add<Group, First>()
|
||||
.set<Position>({6, 6})
|
||||
.add<Tag>();
|
||||
|
||||
// The query cache now looks like this:
|
||||
// - group First:
|
||||
// - table [Position, (Group, First)]
|
||||
// - table [Postion, Tag, (Group, First)]
|
||||
//
|
||||
// - group Second:
|
||||
// - table [Position, (Group, Second)]
|
||||
// - table [Postion, Tag, (Group, Second)]
|
||||
//
|
||||
// - group Third:
|
||||
// - table [Position, (Group, Third)]
|
||||
// - table [Postion, Tag, (Group, Third)]
|
||||
//
|
||||
|
||||
std::cout << "\n";
|
||||
|
||||
q.iter([&](flecs::iter& it, Position *p) {
|
||||
flecs::entity group = ecs.entity(it.group_id());
|
||||
group_ctx *ctx = static_cast<group_ctx*>(q.group_ctx(group));
|
||||
std::cout << " - group " << group.path() << ": table ["
|
||||
<< it.table().str() << "]\n";
|
||||
std::cout << " counter: " << ctx->counter << "\n";
|
||||
|
||||
for (auto i : it) {
|
||||
std::cout << " {" << p[i].x << ", " << p[i].y << "}\n";
|
||||
}
|
||||
|
||||
std::cout << "\n";
|
||||
});
|
||||
|
||||
// Deleting the query will call the on_group_deleted callback
|
||||
q.destruct();
|
||||
|
||||
// Output:
|
||||
// Group Third created
|
||||
// Group Second created
|
||||
// Group First created
|
||||
//
|
||||
// - group ::First: table [Position, (Group,First)]
|
||||
// counter: 3
|
||||
// {3, 3}
|
||||
//
|
||||
// - group ::First: table [Position, Tag, (Group,First)]
|
||||
// counter: 3
|
||||
// {6, 6}
|
||||
//
|
||||
// - group ::Second: table [Position, (Group,Second)]
|
||||
// counter: 2
|
||||
// {2, 2}
|
||||
//
|
||||
// - group ::Second: table [Position, Tag, (Group,Second)]
|
||||
// counter: 2
|
||||
// {5, 5}
|
||||
//
|
||||
// - group ::Third: table [Position, (Group,Third)]
|
||||
// counter: 1
|
||||
// {1, 1}
|
||||
//
|
||||
// - group ::Third: table [Position, Tag, (Group,Third)]
|
||||
// counter: 1
|
||||
// {4, 4}
|
||||
//
|
||||
// Group Third deleted
|
||||
// Group Second deleted
|
||||
// Group First deleted
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef GROUP_BY_CUSTOM_H
|
||||
#define GROUP_BY_CUSTOM_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
#include "group_by_custom/bake_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef GROUP_BY_CUSTOM_BAKE_CONFIG_H
|
||||
#define GROUP_BY_CUSTOM_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "group_by_custom",
|
||||
"type": "application",
|
||||
"value": {
|
||||
"use": [
|
||||
"flecs"
|
||||
],
|
||||
"public": false,
|
||||
"language": "c++"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
#include <group_by_custom.h>
|
||||
#include <iostream>
|
||||
|
||||
// This example does the same as the group_by example, but with a custom
|
||||
// group_by function. A custom function makes it possible to customize how a
|
||||
// group id is calculated for a table.
|
||||
|
||||
struct Position {
|
||||
double x, y;
|
||||
};
|
||||
|
||||
// Dummy tag to put entities in different tables
|
||||
struct Tag { };
|
||||
|
||||
// Create a relationship to use for the group_by function. Tables will
|
||||
// be assigned the relationship target as group id
|
||||
struct Group { };
|
||||
|
||||
// Targets for the relationship, which will be used as group ids.
|
||||
struct First { };
|
||||
struct Second { };
|
||||
struct Third { };
|
||||
|
||||
uint64_t group_by_relation(flecs::world_t *ecs, flecs::table_t *table,
|
||||
flecs::entity_t id, void *)
|
||||
{
|
||||
// Use ecs_search to find the target for the relationship in the table
|
||||
flecs::id_t match;
|
||||
if (ecs_search(ecs, table, flecs::id(id, flecs::Wildcard), &match) != -1) {
|
||||
return flecs::id(ecs, match).second(); // First, Second or Third
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
flecs::world ecs;
|
||||
|
||||
// Register components in order so that id for First is lower than Third
|
||||
ecs.component<First>();
|
||||
ecs.component<Second>();
|
||||
ecs.component<Third>();
|
||||
|
||||
// Grouped query
|
||||
flecs::query<Position> q = ecs.query_builder<Position>()
|
||||
.group_by<Group>(group_by_relation)
|
||||
.build();
|
||||
|
||||
// Create entities in 6 different tables with 3 group ids
|
||||
ecs.entity().add<Group, Third>()
|
||||
.set<Position>({1, 1});
|
||||
ecs.entity().add<Group, Second>()
|
||||
.set<Position>({2, 2});
|
||||
ecs.entity().add<Group, First>()
|
||||
.set<Position>({3, 3});
|
||||
|
||||
ecs.entity().add<Group, Third>()
|
||||
.set<Position>({4, 4})
|
||||
.add<Tag>();
|
||||
ecs.entity().add<Group, Second>()
|
||||
.set<Position>({5, 5})
|
||||
.add<Tag>();
|
||||
ecs.entity().add<Group, First>()
|
||||
.set<Position>({6, 6})
|
||||
.add<Tag>();
|
||||
|
||||
// The query cache now looks like this:
|
||||
// - group First:
|
||||
// - table [Position, (Group, First)]
|
||||
// - table [Postion, Tag, (Group, First)]
|
||||
//
|
||||
// - group Second:
|
||||
// - table [Position, (Group, Second)]
|
||||
// - table [Postion, Tag, (Group, Second)]
|
||||
//
|
||||
// - group Third:
|
||||
// - table [Position, (Group, Third)]
|
||||
// - table [Postion, Tag, (Group, Third)]
|
||||
//
|
||||
|
||||
q.iter([&](flecs::iter& it, Position *p) {
|
||||
flecs::entity group = ecs.entity(it.group_id());
|
||||
std::cout << " - group " << group.path() << ": table ["
|
||||
<< it.table().str() << "]\n";
|
||||
|
||||
for (auto i : it) {
|
||||
std::cout << " {" << p[i].x << ", " << p[i].y << "}\n";
|
||||
}
|
||||
|
||||
std::cout << "\n";
|
||||
});
|
||||
|
||||
// Output:
|
||||
// - group ::First: table [Position, (Group,First)]
|
||||
// {3, 3}
|
||||
//
|
||||
// - group ::First: table [Position, Tag, (Group,First)]
|
||||
// {6, 6}
|
||||
//
|
||||
// - group ::Second: table [Position, (Group,Second)]
|
||||
// {2, 2}
|
||||
//
|
||||
// - group ::Second: table [Position, Tag, (Group,Second)]
|
||||
// {5, 5}
|
||||
//
|
||||
// - group ::Third: table [Position, (Group,Third)]
|
||||
// {1, 1}
|
||||
//
|
||||
// - group ::Third: table [Position, Tag, (Group,Third)]
|
||||
// {4, 4}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef GROUP_ITER_H
|
||||
#define GROUP_ITER_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
#include "group_iter/bake_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef GROUP_ITER_BAKE_CONFIG_H
|
||||
#define GROUP_ITER_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "group_iter",
|
||||
"type": "application",
|
||||
"value": {
|
||||
"use": [
|
||||
"flecs"
|
||||
],
|
||||
"language": "c++",
|
||||
"public": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
#include <group_iter.h>
|
||||
#include <iostream>
|
||||
|
||||
// A group iterator iterates over a single group of a grouped query (see the
|
||||
// group_by example for more details). This can be useful when an application
|
||||
// may need to match different entities based on the context of the game, such
|
||||
// as editor mode, day/night, inside/outside or location in the world.
|
||||
//
|
||||
// One example is that of an open game which is divided up into world
|
||||
// cells. Even though a world may contain many entities, only the entities in
|
||||
// cells close to the player need to be processed.
|
||||
//
|
||||
// Instead of creating a cached query per world cell, which could be expensive
|
||||
// as there are more caches to keep in sync, applications can create a single
|
||||
// query grouped by world cell, and use group iterators to only iterate the
|
||||
// necessary cells.
|
||||
|
||||
// A world cell relationship with four cells
|
||||
struct WorldCell {};
|
||||
struct Cell_0_0 {};
|
||||
struct Cell_0_1 {};
|
||||
struct Cell_1_0 {};
|
||||
struct Cell_1_1 {};
|
||||
|
||||
// Npc tags
|
||||
struct Npc {};
|
||||
struct Merchant {};
|
||||
struct Soldier {};
|
||||
struct Beggar {};
|
||||
struct Mage {};
|
||||
|
||||
int main() {
|
||||
flecs::world ecs;
|
||||
|
||||
// Create npc's in world cell 0_0
|
||||
ecs.entity().add<WorldCell, Cell_0_0>()
|
||||
.add<Merchant>()
|
||||
.add<Npc>();
|
||||
ecs.entity().add<WorldCell, Cell_0_0>()
|
||||
.add<Merchant>()
|
||||
.add<Npc>();
|
||||
|
||||
// Create npc's in world cell 0_1
|
||||
ecs.entity().add<WorldCell, Cell_0_1>()
|
||||
.add<Beggar>()
|
||||
.add<Npc>();
|
||||
ecs.entity().add<WorldCell, Cell_0_1>()
|
||||
.add<Soldier>()
|
||||
.add<Npc>();
|
||||
|
||||
// Create npc's in world cell 1_0
|
||||
ecs.entity().add<WorldCell, Cell_1_0>()
|
||||
.add<Mage>()
|
||||
.add<Npc>();
|
||||
ecs.entity().add<WorldCell, Cell_1_0>()
|
||||
.add<Beggar>()
|
||||
.add<Npc>();
|
||||
|
||||
// Create npc's in world cell 1_1
|
||||
ecs.entity().add<WorldCell, Cell_1_1>()
|
||||
.add<Soldier>()
|
||||
.add<Npc>();
|
||||
|
||||
flecs::query<Npc> q = ecs.query_builder<Npc>()
|
||||
.group_by<WorldCell>()
|
||||
.build();
|
||||
|
||||
// Iterate all tables
|
||||
std::cout << "All tables:\n";
|
||||
q.iter([&](flecs::iter& it) {
|
||||
flecs::entity group = ecs.entity(it.group_id());
|
||||
std::cout << " - group " << group.path() << ": table ["
|
||||
<< it.table().str() << "]\n";
|
||||
});
|
||||
|
||||
std::cout << "\n";
|
||||
|
||||
// Only iterate entities in cell 1_0
|
||||
std::cout << "Tables for cell 1_0:\n";
|
||||
q.iter().set_group<Cell_1_0>().iter([&](flecs::iter& it) {
|
||||
flecs::entity group = ecs.entity(it.group_id());
|
||||
std::cout << " - group " << group.path() << ": table ["
|
||||
<< it.table().str() << "]\n";
|
||||
});
|
||||
|
||||
// Output:
|
||||
// All tables:
|
||||
// - group ::Cell_0_0: table [Merchant, Npc, (WorldCell,Cell_0_0)]
|
||||
// - group ::Cell_0_1: table [Npc, Beggar, (WorldCell,Cell_0_1)]
|
||||
// - group ::Cell_0_1: table [Npc, Soldier, (WorldCell,Cell_0_1)]
|
||||
// - group ::Cell_1_0: table [Npc, Mage, (WorldCell,Cell_1_0)]
|
||||
// - group ::Cell_1_0: table [Npc, Beggar, (WorldCell,Cell_1_0)]
|
||||
// - group ::Cell_1_1: table [Npc, Soldier, (WorldCell,Cell_1_1)]
|
||||
//
|
||||
// Tables for cell 1_0:
|
||||
// - group ::Cell_1_0: table [Npc, Mage, (WorldCell,Cell_1_0)]
|
||||
// - group ::Cell_1_0: table [Npc, Beggar, (WorldCell,Cell_1_0)]
|
||||
}
|
||||
5
engine/libs/flecs/examples/cpp/queries/hierarchy/.gitignore
vendored
Normal file
5
engine/libs/flecs/examples/cpp/queries/hierarchy/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
.bake_cache
|
||||
.DS_Store
|
||||
.vscode
|
||||
gcov
|
||||
bin
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef HIERARCHY_H
|
||||
#define HIERARCHY_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
#include "hierarchy/bake_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef HIERARCHY_BAKE_CONFIG_H
|
||||
#define HIERARCHY_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"id": "hierarchy",
|
||||
"type": "application",
|
||||
"value": {
|
||||
"author": "Jane Doe",
|
||||
"description": "A simple hello world flecs application",
|
||||
"use": [
|
||||
"flecs"
|
||||
],
|
||||
"language": "c++"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
#include <hierarchy.h>
|
||||
#include <iostream>
|
||||
|
||||
struct Position {
|
||||
double x, y;
|
||||
};
|
||||
|
||||
// Tags for local/world position
|
||||
struct Local { };
|
||||
struct World { };
|
||||
|
||||
int main(int, char *[]) {
|
||||
flecs::world ecs;
|
||||
|
||||
// Create a hierarchy. For an explanation see the entities/hierarchy example
|
||||
flecs::entity sun = ecs.entity("Sun")
|
||||
.add<Position, World>()
|
||||
.set<Position, Local>({1, 1});
|
||||
|
||||
ecs.entity("Mercury")
|
||||
.child_of(sun)
|
||||
.add<Position, World>()
|
||||
.set<Position, Local>({1, 1});
|
||||
|
||||
ecs.entity("Venus")
|
||||
.child_of(sun)
|
||||
.add<Position, World>()
|
||||
.set<Position, Local>({2, 2});
|
||||
|
||||
flecs::entity earth = ecs.entity("Earth")
|
||||
.child_of(sun)
|
||||
.add<Position, World>()
|
||||
.set<Position, Local>({3, 3});
|
||||
|
||||
ecs.entity("Moon")
|
||||
.child_of(earth)
|
||||
.add<Position, World>()
|
||||
.set<Position, Local>({0.1, 0.1});
|
||||
|
||||
// Create a hierarchical query to compute the global position from the
|
||||
// local position and the parent position.
|
||||
flecs::query<const Position, const Position, Position> q =
|
||||
ecs.query_builder<const Position, const Position, Position>()
|
||||
// Modify terms from template to make sure the query selects the
|
||||
// local, world and parent position components.
|
||||
.term_at(1).second<Local>()
|
||||
.term_at(2).second<World>()
|
||||
.term_at(3).second<World>()
|
||||
|
||||
// Extend the 2nd query argument to select it from the parent
|
||||
.term_at(2)
|
||||
// Get from the parent, in breadth-first order (cascade)
|
||||
.parent().cascade()
|
||||
// Make term component optional so we also match the root (sun)
|
||||
.optional()
|
||||
// Finalize the query
|
||||
.build();
|
||||
|
||||
// Do the transform
|
||||
q.iter([](flecs::iter& it,
|
||||
const Position *p, const Position *p_parent, Position *p_out)
|
||||
{
|
||||
for (auto i : it) {
|
||||
p_out[i].x = p[i].x;
|
||||
p_out[i].y = p[i].y;
|
||||
if (p_parent) {
|
||||
p_out[i].x += p_parent->x;
|
||||
p_out[i].y += p_parent->y;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Print world positions
|
||||
ecs.each([](flecs::entity e, flecs::pair<Position, World> p) {
|
||||
std::cout << e.name() << ": {" << p->x << ", " << p->y << "}\n";
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef INSTANCING_H
|
||||
#define INSTANCING_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
#include "instancing/bake_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef INSTANCING_BAKE_CONFIG_H
|
||||
#define INSTANCING_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "instancing",
|
||||
"type": "application",
|
||||
"value": {
|
||||
"use": [
|
||||
"flecs"
|
||||
],
|
||||
"language": "c++",
|
||||
"public": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
#include <instancing.h>
|
||||
#include <iostream>
|
||||
|
||||
/* Instancing is the ability of queries to iterate results with fields that have
|
||||
* different numbers of elements. The term "instancing" is borrowed from
|
||||
* graphics APIs, where it means reusing the same data for multiple "instances".
|
||||
*
|
||||
* Query instancing works in much the same way. By default queries match all
|
||||
* components on the same entity. It is however possible to request data from
|
||||
* other entities, like getting the Position from the entity's parent.
|
||||
*
|
||||
* Instancing refers to the ability of queries to iterate components for
|
||||
* multiple entities while at the same time providing "instanced" components,
|
||||
* which are always provided one element at a time.
|
||||
*
|
||||
* Instancing is often used in combination with parent-child relationships and
|
||||
* prefabs, but is applicable to any kind of query where some of the terms are
|
||||
* matched on N entities, and some on a single entity.
|
||||
*
|
||||
* By default queries are not instanced, which means that if a result contains
|
||||
* mixed fields, entities will be iterated one by one instead of in batches.
|
||||
* This is safer, as code doesn't have to do anything different for owned and
|
||||
* shared fields, but does come at a performance penalty.
|
||||
*
|
||||
* The each() iterator function always uses an instanced iterator under the
|
||||
* hood. This is transparent to the application, but improves performance. For
|
||||
* this reason using each() can be faster than using uninstanced iter().
|
||||
*/
|
||||
|
||||
struct Position {
|
||||
double x, y;
|
||||
};
|
||||
|
||||
struct Velocity {
|
||||
double x, y;
|
||||
};
|
||||
|
||||
int main(int, char *[]) {
|
||||
flecs::world ecs;
|
||||
|
||||
// Create a query for Position, Velocity. We'll create a few entities that
|
||||
// have Velocity as owned and shared component.
|
||||
flecs::query<Position, const Velocity> q =
|
||||
ecs.query_builder<Position, const Velocity>()
|
||||
.term_at(1).self() // Position must always be owned by the entity
|
||||
.instanced() // create instanced query
|
||||
.build();
|
||||
|
||||
// Create a prefab with Velocity. Prefabs are not matched with queries.
|
||||
flecs::entity prefab = ecs.prefab("p")
|
||||
.set<Velocity>({1, 2});
|
||||
|
||||
// Create a few entities that own Position & share Velocity from the prefab.
|
||||
ecs.entity("e1").is_a(prefab)
|
||||
.set<Position>({10, 20});
|
||||
|
||||
ecs.entity("e2").is_a(prefab)
|
||||
.set<Position>({10, 20});
|
||||
|
||||
// Create a few entities that own all components
|
||||
ecs.entity("e3")
|
||||
.set<Position>({10, 20})
|
||||
.set<Velocity>({3, 4});
|
||||
|
||||
ecs.entity("e4")
|
||||
.set<Position>({10, 20})
|
||||
.set<Velocity>({4, 5});
|
||||
|
||||
|
||||
// Iterate the instanced query. Note how when a query is instanced, it needs
|
||||
// to check whether a field is owned or not in order to know how to access
|
||||
// it. In the case of an owned field it is iterated as an array, whereas
|
||||
// in the case of a shared field, it is accessed as a pointer.
|
||||
q.iter([](flecs::iter& it, Position *p, const Velocity *v) {
|
||||
|
||||
// Check if Velocity is owned, in which case it's accessed as array.
|
||||
// Position will always be owned, since we set the term to Self.
|
||||
if (it.is_self(2)) { // Velocity is term 2
|
||||
std::cout << "Velocity is owned\n";
|
||||
for (auto i : it) {
|
||||
p[i].x += v[i].x;
|
||||
p[i].y += v[i].y;
|
||||
std::cout << it.entity(i).name() <<
|
||||
": {" << p[i].x << ", " << p[i].y << "}\n";
|
||||
}
|
||||
|
||||
// If Velocity is shared, access the field as a pointer.
|
||||
} else {
|
||||
std::cout << "Velocity is shared\n";
|
||||
for (auto i : it) {
|
||||
p[i].x += v->x;
|
||||
p[i].y += v->y;
|
||||
std::cout << it.entity(i).name() <<
|
||||
": {" << p[i].x << ", " << p[i].y << "}\n";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
16
engine/libs/flecs/examples/cpp/queries/iter/include/iter.h
Normal file
16
engine/libs/flecs/examples/cpp/queries/iter/include/iter.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef ITER_H
|
||||
#define ITER_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
#include "iter/bake_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef ITER_BAKE_CONFIG_H
|
||||
#define ITER_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
|
||||
#endif
|
||||
|
||||
11
engine/libs/flecs/examples/cpp/queries/iter/project.json
Normal file
11
engine/libs/flecs/examples/cpp/queries/iter/project.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "iter",
|
||||
"type": "application",
|
||||
"value": {
|
||||
"use": [
|
||||
"flecs"
|
||||
],
|
||||
"language": "c++",
|
||||
"public": false
|
||||
}
|
||||
}
|
||||
65
engine/libs/flecs/examples/cpp/queries/iter/src/main.cpp
Normal file
65
engine/libs/flecs/examples/cpp/queries/iter/src/main.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
#include <iter.h>
|
||||
#include <iostream>
|
||||
|
||||
struct Position {
|
||||
double x, y;
|
||||
};
|
||||
|
||||
struct Velocity {
|
||||
double x, y;
|
||||
};
|
||||
|
||||
struct Mass {
|
||||
double value;
|
||||
};
|
||||
|
||||
int main(int, char *[]) {
|
||||
flecs::world ecs;
|
||||
|
||||
// Create a query for Position, Velocity.
|
||||
flecs::query<Position, const Velocity> q =
|
||||
ecs.query<Position, const Velocity>();
|
||||
|
||||
// Create a few test entities for a Position, Velocity query
|
||||
ecs.entity("e1")
|
||||
.set<Position>({10, 20})
|
||||
.set<Velocity>({1, 2});
|
||||
|
||||
ecs.entity("e2")
|
||||
.set<Position>({10, 20})
|
||||
.set<Velocity>({3, 4});
|
||||
|
||||
ecs.entity("e3")
|
||||
.set<Position>({10, 20})
|
||||
.set<Velocity>({4, 5})
|
||||
.set<Mass>({50});
|
||||
|
||||
// The iter function provides a flecs::iter object which contains all sorts
|
||||
// of information on the entities currently being iterated.
|
||||
// The function passed to iter is by default called for each table the query
|
||||
// is matched with.
|
||||
q.iter([&](flecs::iter& it, Position *p, const Velocity *v) {
|
||||
// Print the table & number of entities matched in current callback
|
||||
std::cout << "Table [" << it.type().str() << "]" << std::endl;
|
||||
std::cout << " - number of entities: " << it.count() << std::endl;
|
||||
|
||||
// Print information about the components being matched
|
||||
for (int i = 1; i <= it.field_count(); i ++) {
|
||||
std::cout << " - term " << i << ": " << std::endl;
|
||||
std::cout << " - component: " << it.id(i).str() << std::endl;
|
||||
std::cout << " - type size: " << it.size(i) << std::endl;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
// Iterate entities
|
||||
for (auto i : it) {
|
||||
p[i].x += v[i].x;
|
||||
p[i].y += v[i].y;
|
||||
std::cout << " - " << it.entity(i).name() <<
|
||||
": {" << p[i].x << ", " << p[i].y << "}\n";
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef SINGLETON_H
|
||||
#define SINGLETON_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
#include "singleton/bake_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef SINGLETON_BAKE_CONFIG_H
|
||||
#define SINGLETON_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "singleton",
|
||||
"type": "application",
|
||||
"value": {
|
||||
"use": [
|
||||
"flecs"
|
||||
],
|
||||
"language": "c++",
|
||||
"public": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#include <singleton.h>
|
||||
#include <iostream>
|
||||
|
||||
// This example shows how to use singleton components in queries.
|
||||
|
||||
// Singleton component
|
||||
struct Gravity {
|
||||
double value;
|
||||
};
|
||||
|
||||
// Entity component
|
||||
struct Velocity {
|
||||
double x;
|
||||
double y;
|
||||
};
|
||||
|
||||
int main(int, char *[]) {
|
||||
flecs::world world;
|
||||
|
||||
// Set singleton
|
||||
world.set<Gravity>({ 9.81 });
|
||||
|
||||
// Set Velocity
|
||||
world.entity("e1").set<Velocity>({0, 0});
|
||||
world.entity("e2").set<Velocity>({0, 1});
|
||||
world.entity("e3").set<Velocity>({0, 2});
|
||||
|
||||
// Create query that matches Gravity as singleton
|
||||
flecs::query<Velocity, const Gravity> q =
|
||||
world.query_builder<Velocity, const Gravity>()
|
||||
.term_at(2).singleton()
|
||||
.build();
|
||||
|
||||
// In a query string expression you can use the $ shortcut for singletons:
|
||||
// Velocity, Gravity($)
|
||||
|
||||
q.each([](flecs::entity e, Velocity& v, const Gravity& g) {
|
||||
v.y += g.value;
|
||||
std::cout << e.path() << " velocity is {"
|
||||
<< v.x << ", " << v.y << "}" << std::endl;
|
||||
});
|
||||
|
||||
// Output
|
||||
// ::e1 velocity is {0, 9.81}
|
||||
// ::e2 velocity is {0, 10.81}
|
||||
// ::e3 velocity is {0, 11.81}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef SORTING_H
|
||||
#define SORTING_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
#include "sorting/bake_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef SORTING_BAKE_CONFIG_H
|
||||
#define SORTING_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
|
||||
#endif
|
||||
|
||||
11
engine/libs/flecs/examples/cpp/queries/sorting/project.json
Normal file
11
engine/libs/flecs/examples/cpp/queries/sorting/project.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "sorting",
|
||||
"type": "application",
|
||||
"value": {
|
||||
"use": [
|
||||
"flecs"
|
||||
],
|
||||
"language": "c++",
|
||||
"public": false
|
||||
}
|
||||
}
|
||||
88
engine/libs/flecs/examples/cpp/queries/sorting/src/main.cpp
Normal file
88
engine/libs/flecs/examples/cpp/queries/sorting/src/main.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#include <sorting.h>
|
||||
#include <iostream>
|
||||
|
||||
struct Position {
|
||||
double x, y;
|
||||
};
|
||||
|
||||
// Order by x member of Position */
|
||||
int compare_position(
|
||||
flecs::entity_t e1,
|
||||
const Position *p1,
|
||||
flecs::entity_t e2,
|
||||
const Position *p2)
|
||||
{
|
||||
(void)e1;
|
||||
(void)e2;
|
||||
return (p1->x > p2->x) - (p1->x < p2->x);
|
||||
}
|
||||
|
||||
// Iterate query, printed values will be ordered
|
||||
void print_query(flecs::query<const Position>& q) {
|
||||
q.each([](flecs::entity, const Position& p) {
|
||||
std::cout << "{" << p.x << "," << p.y << "}" << std::endl;
|
||||
});
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
flecs::world ecs(argc, argv);
|
||||
|
||||
// Create entities, set Position in random order
|
||||
flecs::entity e = ecs.entity().set<Position>({1, 0});
|
||||
ecs.entity().set<Position>({6, 0});
|
||||
ecs.entity().set<Position>({2, 0});
|
||||
ecs.entity().set<Position>({5, 0});
|
||||
ecs.entity().set<Position>({4, 0});
|
||||
|
||||
// Create a sorted system
|
||||
flecs::system sys = ecs.system<const Position>()
|
||||
.order_by(compare_position)
|
||||
.each([](const Position &p) {
|
||||
std::cout << "{" << p.x << "," << p.y << "}" << std::endl;
|
||||
});
|
||||
|
||||
// Create a sorted query
|
||||
flecs::query<const Position> q = ecs.query_builder<const Position>()
|
||||
.order_by(compare_position)
|
||||
.build();
|
||||
|
||||
// Iterate query, print values of Position
|
||||
std::cout << "-- First iteration\n";
|
||||
print_query(q);
|
||||
|
||||
// Change the value of one entity, invalidating the order
|
||||
e.set<Position>({7, 0});
|
||||
|
||||
// Iterate query again, printed values are still ordered
|
||||
std::cout << "\n-- Second iteration";
|
||||
print_query(q);
|
||||
|
||||
// Create new entity to show that data is also sorted for system
|
||||
ecs.entity().set<Position>({3, 0});
|
||||
|
||||
// Run system, output will be sorted
|
||||
std::cout << "\n-- System iteration";
|
||||
sys.run();
|
||||
|
||||
// Output
|
||||
// -- First iteration
|
||||
// {1,0}
|
||||
// {2,0}
|
||||
// {4,0}
|
||||
// {5,0}
|
||||
// {6,0}
|
||||
//
|
||||
// -- Second iteration{2,0}
|
||||
// {4,0}
|
||||
// {5,0}
|
||||
// {6,0}
|
||||
// {7,0}
|
||||
//
|
||||
// -- System iteration{2,0}
|
||||
// {3,0}
|
||||
// {4,0}
|
||||
// {5,0}
|
||||
// {6,0}
|
||||
// {7,0}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef WILDCARDS_H
|
||||
#define WILDCARDS_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
#include "wildcards/bake_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef WILDCARDS_BAKE_CONFIG_H
|
||||
#define WILDCARDS_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "wildcards",
|
||||
"type": "application",
|
||||
"value": {
|
||||
"use": [
|
||||
"flecs"
|
||||
],
|
||||
"language": "c++",
|
||||
"public": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#include <wildcards.h>
|
||||
#include <iostream>
|
||||
|
||||
// Queries can have wildcard terms that can match multiple instances of a
|
||||
// relationship or relationship target.
|
||||
|
||||
struct Eats {
|
||||
int amount;
|
||||
};
|
||||
|
||||
struct Apples { };
|
||||
struct Pears { };
|
||||
|
||||
int main(int, char *[]) {
|
||||
flecs::world ecs;
|
||||
|
||||
// Create a query that matches edible components
|
||||
flecs::query<Eats> q = ecs.query_builder<Eats>()
|
||||
.term_at(1).second(flecs::Wildcard) // Change first argument to (Eats, *)
|
||||
.build();
|
||||
|
||||
// Create a few entities that match the query
|
||||
ecs.entity("Bob")
|
||||
.set<Eats, Apples>({10})
|
||||
.set<Eats, Pears>({5});
|
||||
|
||||
ecs.entity("Alice")
|
||||
.set<Eats, Apples>({4});
|
||||
|
||||
// Iterate the query with a flecs::iter. This makes it possible to inspect
|
||||
// the pair that we are currently matched with.
|
||||
q.each([](flecs::iter& it, size_t index, Eats& eats) {
|
||||
flecs::entity e = it.entity(index);
|
||||
flecs::entity food = it.pair(1).second();
|
||||
|
||||
std::cout << e.name() << " eats "
|
||||
<< eats.amount << " " << food.name() << std::endl;
|
||||
});
|
||||
|
||||
// Output:
|
||||
// Bob eats 10 Apples
|
||||
// Bob eats 5 Pears
|
||||
// Alice eats 4 Apples
|
||||
}
|
||||
16
engine/libs/flecs/examples/cpp/queries/with/include/with.h
Normal file
16
engine/libs/flecs/examples/cpp/queries/with/include/with.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef WITH_H
|
||||
#define WITH_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
#include "with/bake_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef WITH_BAKE_CONFIG_H
|
||||
#define WITH_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
|
||||
#endif
|
||||
|
||||
11
engine/libs/flecs/examples/cpp/queries/with/project.json
Normal file
11
engine/libs/flecs/examples/cpp/queries/with/project.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "with",
|
||||
"type": "application",
|
||||
"value": {
|
||||
"use": [
|
||||
"flecs"
|
||||
],
|
||||
"language": "c++",
|
||||
"public": false
|
||||
}
|
||||
}
|
||||
44
engine/libs/flecs/examples/cpp/queries/with/src/main.cpp
Normal file
44
engine/libs/flecs/examples/cpp/queries/with/src/main.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include <with.h>
|
||||
#include <iostream>
|
||||
|
||||
struct Position {
|
||||
double x, y;
|
||||
};
|
||||
|
||||
struct Npc { };
|
||||
|
||||
int main(int, char *[]) {
|
||||
flecs::world ecs;
|
||||
|
||||
// Create a query for Position, Npc. By adding the Npc component using the
|
||||
// "with" method, the component is not a part of the query type, and as a
|
||||
// result does not become part of the function signatures of each and iter.
|
||||
// This is useful for things like tags, which because they don't have a
|
||||
// value are less useful to pass to the each/iter functions as argument.
|
||||
flecs::query<Position> q = ecs.query_builder<Position>()
|
||||
.with<Npc>()
|
||||
.build();
|
||||
|
||||
// Create a few test entities for the Position, Npc query
|
||||
ecs.entity("e1")
|
||||
.set<Position>({10, 20})
|
||||
.add<Npc>();
|
||||
|
||||
ecs.entity("e2")
|
||||
.set<Position>({10, 20})
|
||||
.add<Npc>();
|
||||
|
||||
// This entity will not match as it does not have Position, Npc
|
||||
ecs.entity("e3")
|
||||
.set<Position>({10, 20});
|
||||
|
||||
|
||||
// Note how the Npc tag is not part of the each signature
|
||||
q.each([](flecs::entity e, Position& p) {
|
||||
std::cout << e.name() << ": {" << p.x << ", " << p.y << "}\n";
|
||||
});
|
||||
|
||||
// Output:
|
||||
// e1: {10, 20}
|
||||
// e2: {10, 20}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef WITHOUT_H
|
||||
#define WITHOUT_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
#include "without/bake_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef WITHOUT_BAKE_CONFIG_H
|
||||
#define WITHOUT_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
|
||||
#endif
|
||||
|
||||
11
engine/libs/flecs/examples/cpp/queries/without/project.json
Normal file
11
engine/libs/flecs/examples/cpp/queries/without/project.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "without",
|
||||
"type": "application",
|
||||
"value": {
|
||||
"use": [
|
||||
"flecs"
|
||||
],
|
||||
"language": "c++",
|
||||
"public": false
|
||||
}
|
||||
}
|
||||
46
engine/libs/flecs/examples/cpp/queries/without/src/main.cpp
Normal file
46
engine/libs/flecs/examples/cpp/queries/without/src/main.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <without.h>
|
||||
#include <iostream>
|
||||
|
||||
struct Position {
|
||||
double x, y;
|
||||
};
|
||||
|
||||
struct Npc { };
|
||||
|
||||
int main(int, char *[]) {
|
||||
flecs::world ecs;
|
||||
|
||||
// Create a query for Position, !Npc. By adding the Npc component using the
|
||||
// "without" method, the component is not a part of the query type, and as a
|
||||
// result does not become part of the function signatures of each and iter.
|
||||
// This is useful for things like tags, which because they don't have a
|
||||
// value are less useful to pass to the each/iter functions as argument.
|
||||
//
|
||||
// The without method is short for:
|
||||
// .term<Npc>().not_()
|
||||
flecs::query<Position> q = ecs.query_builder<Position>()
|
||||
.without<Npc>()
|
||||
.build();
|
||||
|
||||
// Create a few test entities for the Position query
|
||||
ecs.entity("e1")
|
||||
.set<Position>({10, 20});
|
||||
|
||||
ecs.entity("e2")
|
||||
.set<Position>({10, 20});
|
||||
|
||||
// This entity will not match as it has Npc
|
||||
ecs.entity("e3")
|
||||
.set<Position>({10, 20})
|
||||
.add<Npc>();
|
||||
|
||||
|
||||
// Note how the Npc tag is not part of the each signature
|
||||
q.each([](flecs::entity e, Position& p) {
|
||||
std::cout << e.name() << ": {" << p.x << ", " << p.y << "}\n";
|
||||
});
|
||||
|
||||
// Output:
|
||||
// e1: {10, 20}
|
||||
// e2: {10, 20}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef WORLD_QUERY_H
|
||||
#define WORLD_QUERY_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
#include "world_query/bake_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* This file is generated by bake.lang.c for your convenience. Headers of
|
||||
* dependencies will automatically show up in this file. Include bake_config.h
|
||||
* in your main project file. Do not edit! */
|
||||
|
||||
#ifndef WORLD_QUERY_BAKE_CONFIG_H
|
||||
#define WORLD_QUERY_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "world_query",
|
||||
"type": "application",
|
||||
"value": {
|
||||
"use": [
|
||||
"flecs"
|
||||
],
|
||||
"language": "c++",
|
||||
"public": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#include <world_query.h>
|
||||
#include <iostream>
|
||||
|
||||
struct Position {
|
||||
double x, y;
|
||||
};
|
||||
|
||||
struct Velocity {
|
||||
double x, y;
|
||||
};
|
||||
|
||||
int main(int, char *[]) {
|
||||
flecs::world ecs;
|
||||
|
||||
// Create a few test entities for a Position, Velocity query
|
||||
ecs.entity("e1")
|
||||
.set<Position>({10, 20})
|
||||
.set<Velocity>({1, 2});
|
||||
|
||||
ecs.entity("e2")
|
||||
.set<Position>({10, 20})
|
||||
.set<Velocity>({3, 4});
|
||||
|
||||
// This entity will not match as it does not have Position, Velocity
|
||||
ecs.entity("e3")
|
||||
.set<Position>({10, 20});
|
||||
|
||||
// Ad hoc queries are bit slower to iterate than flecs::query, but are
|
||||
// faster to create, and in most cases require no allocations. Under the
|
||||
// hood this API uses flecs::filter, which can be used directly for more
|
||||
// complex queries.
|
||||
ecs.each([](flecs::entity e, Position& p, Velocity& v) {
|
||||
p.x += v.x;
|
||||
p.y += v.y;
|
||||
std::cout << e.name() << ": {" << p.x << ", " << p.y << "}\n";
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user