Properly link flecs library

This commit is contained in:
2023-11-09 11:38:29 +01:00
parent dc585396c3
commit 8edcf9305c
1392 changed files with 390081 additions and 164 deletions

View File

@@ -0,0 +1,5 @@
.bake_cache
.DS_Store
.vscode
gcov
bin

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,12 @@
{
"id": "basics",
"type": "application",
"value": {
"author": "Jane Doe",
"description": "A simple hello world flecs application",
"use": [
"flecs"
],
"language": "c++"
}
}

View 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";
}
});
}

View File

@@ -0,0 +1,5 @@
.bake_cache
.DS_Store
.vscode
gcov
bin

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,10 @@
{
"id": "change_tracking",
"type": "application",
"value": {
"use": [
"flecs"
],
"language": "c++"
}
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,11 @@
{
"id": "find_entity",
"type": "application",
"value": {
"use": [
"flecs"
],
"language": "c++",
"public": false
}
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,11 @@
{
"id": "group_by",
"type": "application",
"value": {
"use": [
"flecs"
],
"language": "c++",
"public": false
}
}

View 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}
}

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,11 @@
{
"id": "group_by_callbacks",
"type": "application",
"value": {
"use": [
"flecs"
],
"public": false,
"language": "c++"
}
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,11 @@
{
"id": "group_by_custom",
"type": "application",
"value": {
"use": [
"flecs"
],
"public": false,
"language": "c++"
}
}

View File

@@ -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}
}

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,11 @@
{
"id": "group_iter",
"type": "application",
"value": {
"use": [
"flecs"
],
"language": "c++",
"public": false
}
}

View File

@@ -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)]
}

View File

@@ -0,0 +1,5 @@
.bake_cache
.DS_Store
.vscode
gcov
bin

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,12 @@
{
"id": "hierarchy",
"type": "application",
"value": {
"author": "Jane Doe",
"description": "A simple hello world flecs application",
"use": [
"flecs"
],
"language": "c++"
}
}

View File

@@ -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";
});
}

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,11 @@
{
"id": "instancing",
"type": "application",
"value": {
"use": [
"flecs"
],
"language": "c++",
"public": false
}
}

View File

@@ -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";
}
}
});
}

View 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

View File

@@ -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

View File

@@ -0,0 +1,11 @@
{
"id": "iter",
"type": "application",
"value": {
"use": [
"flecs"
],
"language": "c++",
"public": false
}
}

View 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;
});
}

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,11 @@
{
"id": "singleton",
"type": "application",
"value": {
"use": [
"flecs"
],
"language": "c++",
"public": false
}
}

View File

@@ -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}
}

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,11 @@
{
"id": "sorting",
"type": "application",
"value": {
"use": [
"flecs"
],
"language": "c++",
"public": false
}
}

View 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}
}

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,11 @@
{
"id": "wildcards",
"type": "application",
"value": {
"use": [
"flecs"
],
"language": "c++",
"public": false
}
}

View File

@@ -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
}

View 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

View File

@@ -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

View File

@@ -0,0 +1,11 @@
{
"id": "with",
"type": "application",
"value": {
"use": [
"flecs"
],
"language": "c++",
"public": false
}
}

View 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}
}

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,11 @@
{
"id": "without",
"type": "application",
"value": {
"use": [
"flecs"
],
"language": "c++",
"public": false
}
}

View 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}
}

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,11 @@
{
"id": "world_query",
"type": "application",
"value": {
"use": [
"flecs"
],
"language": "c++",
"public": false
}
}

View File

@@ -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";
});
}