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,16 @@
#ifndef SYSTEMS_H
#define SYSTEMS_H
/* This generated file contains includes for project dependencies */
#include "systems/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 SYSTEMS_BAKE_CONFIG_H
#define SYSTEMS_BAKE_CONFIG_H
/* Headers of public dependencies */
#include <flecs.h>
#endif

View File

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

View File

@@ -0,0 +1,39 @@
#include <systems.h>
#include <iostream>
struct Position {
double x, y;
};
struct Velocity {
double x, y;
};
int main(int, char *[]) {
flecs::world ecs;
// Create a system for Position, Velocity. Systems are like queries (see
// queries) with a function that can be ran or scheduled (see pipeline).
flecs::system s = ecs.system<Position, const Velocity>()
.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";
});
// 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});
// Run the system
s.run();
}

View File

@@ -0,0 +1,16 @@
#ifndef CUSTOM_PHASES_H
#define CUSTOM_PHASES_H
/* This generated file contains includes for project dependencies */
#include "custom_phases/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 CUSTOM_PHASES_BAKE_CONFIG_H
#define CUSTOM_PHASES_BAKE_CONFIG_H
/* Headers of public dependencies */
#include <flecs.h>
#endif

View File

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

View File

@@ -0,0 +1,47 @@
#include <custom_phases.h>
#include <iostream>
// This application demonstrates how to use custom phases for systems. The
// default pipeline will automatically run systems for custom phases as long as
// they have the flecs::Phase tag.
// Dummy system
void Sys(flecs::iter& it) {
std::cout << "system " << it.system().name() << "\n";
}
int main(int argc, char *argv[]) {
flecs::world ecs(argc, argv);
// Create two custom phases that branch off of EcsOnUpdate. Note that the
// phases have the Phase tag, which is necessary for the builtin pipeline
// to discover which systems it should run.
flecs::entity Physics = ecs.entity()
.add(flecs::Phase)
.depends_on(flecs::OnUpdate);
flecs::entity Collisions = ecs.entity()
.add(flecs::Phase)
.depends_on(Physics);
// Create 3 dummy systems.
ecs.system("CollisionSystem")
.kind(Collisions)
.iter(Sys);
ecs.system("PhysicsSystem")
.kind(Physics)
.iter(Sys);
ecs.system("GameSystem")
.kind(flecs::OnUpdate)
.iter(Sys);
// Run pipeline
ecs.progress();
// Output
// system GameSystem
// system PhysicsSystem
// system CollisionSystem
}

View File

@@ -0,0 +1,16 @@
#ifndef CUSTOM_PHASES_NO_BUILTIN_H
#define CUSTOM_PHASES_NO_BUILTIN_H
/* This generated file contains includes for project dependencies */
#include "custom_phases_no_builtin/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 CUSTOM_PHASES_NO_BUILTIN_BAKE_CONFIG_H
#define CUSTOM_PHASES_NO_BUILTIN_BAKE_CONFIG_H
/* Headers of public dependencies */
#include <flecs.h>
#endif

View File

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

View File

@@ -0,0 +1,50 @@
#include <custom_phases_no_builtin.h>
#include <iostream>
// This application demonstrates how to use custom phases for systems. The
// default pipeline will automatically run systems for custom phases as long as
// they have the flecs::Phase tag.
// Dummy system
void Sys(flecs::iter& it) {
std::cout << "system " << it.system().name() << "\n";
}
int main(int argc, char *argv[]) {
flecs::world ecs(argc, argv);
// Create three custom phases. Note that the phases have the Phase tag,
// which is necessary for the builtin pipeline to discover which systems it
// should run.
flecs::entity Update = ecs.entity()
.add(flecs::Phase);
flecs::entity Physics = ecs.entity()
.add(flecs::Phase)
.depends_on(Update);
flecs::entity Collisions = ecs.entity()
.add(flecs::Phase)
.depends_on(Physics);
// Create 3 dummy systems.
ecs.system("CollisionSystem")
.kind(Collisions)
.iter(Sys);
ecs.system("PhysicsSystem")
.kind(Physics)
.iter(Sys);
ecs.system("GameSystem")
.kind(Update)
.iter(Sys);
// Run pipeline
ecs.progress();
// Output
// system GameSystem
// system PhysicsSystem
// system CollisionSystem
}

View File

@@ -0,0 +1,16 @@
#ifndef CUSTOM_PIPELINE_H
#define CUSTOM_PIPELINE_H
/* This generated file contains includes for project dependencies */
#include "custom_pipeline/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 CUSTOM_PIPELINE_BAKE_CONFIG_H
#define CUSTOM_PIPELINE_BAKE_CONFIG_H
/* Headers of public dependencies */
#include <flecs.h>
#endif

View File

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

View File

@@ -0,0 +1,40 @@
#include <custom_pipeline.h>
#include <iostream>
// Custom pipelines make it possible for applications to override which systems
// are ran by a pipeline and how they are ordered. Pipelines are queries under
// the hood, and custom pipelines override the query used for system matching.
// If you only want to use custom phases in addition or in place of the builtin
// phases see the custom_phases and custom_phases_no_builtin examples, as this
// does not require using a custom pipeline.
struct Physics {};
int main(int argc, char *argv[]) {
flecs::world ecs(argc, argv);
// Create a pipeline that matches systems with Physics. Note that this
// pipeline does not require the use of phases (see custom_phases) or of the
// DependsOn relationship.
flecs::entity pipeline = ecs.pipeline()
.with(flecs::System) // Mandatory, must always match systems
.with<Physics>()
.build();
// Configure the world to use the custom pipeline
ecs.set_pipeline(pipeline);
// Create system with Physics tag
ecs.system()
.kind<Physics>()
.iter([](flecs::iter&) {
std::cout << "System ran!\n";
});
// Runs the pipeline & system
ecs.progress();
// Output:
// System ran!
}

View File

@@ -0,0 +1,16 @@
#ifndef CUSTOM_RUNNER_H
#define CUSTOM_RUNNER_H
/* This generated file contains includes for project dependencies */
#include "custom_runner/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 CUSTOM_RUNNER_BAKE_CONFIG_H
#define CUSTOM_RUNNER_BAKE_CONFIG_H
/* Headers of public dependencies */
#include <flecs.h>
#endif

View File

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

View File

@@ -0,0 +1,63 @@
#include <custom_runner.h>
#include <iostream>
// Systems can be created with a custom run function that takes control over the
// entire iteration. By default, a system is invoked once per matched table,
// which means the function can be called multiple times per frame. In some
// cases that's inconvenient, like when a system has things it needs to do only
// once per frame. For these use cases, the run callback can be used which is
// called once per frame per system.
struct Position {
double x, y;
};
struct Velocity {
double x, y;
};
int main(int, char *[]) {
flecs::world ecs;
flecs::system s = ecs.system<Position, const Velocity>()
// The run function has a signature that accepts a C iterator. By
// forwarding the iterator to it->callback, the each function of the
// system is invoked.
.run([](flecs::iter_t *it) {
std::cout << "Move begin\n";
// Walk over the iterator, forward to the system callback
while (ecs_iter_next(it)) {
it->callback(it);
}
std::cout << "Move end\n";
})
.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";
});
// 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});
// Run the system
s.run();
// Output
// Move begin
// e1: {11, 22}
// e2: {13, 24}
// Move end
}

View File

@@ -0,0 +1,16 @@
#ifndef DELTA_TIME_H
#define DELTA_TIME_H
/* This generated file contains includes for project dependencies */
#include "delta_time/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 DELTA_TIME_BAKE_CONFIG_H
#define DELTA_TIME_BAKE_CONFIG_H
/* Headers of public dependencies */
#include <flecs.h>
#endif

View File

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

View File

@@ -0,0 +1,27 @@
#include <delta_time.h>
#include <iostream>
int main(int, char *[]) {
flecs::world ecs;
// Create system that prints delta_time. This system doesn't query for any
// components which means it won't match any entities, but will still be ran
// once for each call to ecs_progress.
ecs.system()
.iter([](flecs::iter& it) {
std::cout << "delta_time: " << it.delta_time() << std::endl;
});
// Call progress with 0.0f for the delta_time parameter. This will cause
// ecs_progress to measure the time passed since the last frame. The
// delta_time of the first frame is a best guess (16ms).
ecs.progress();
// The following calls should print a delta_time of approximately 100ms
ecs_os_sleep(0, 100 * 1000 * 1000);
ecs.progress();
ecs_os_sleep(0, 100 * 1000 * 1000);
ecs.progress();
}

View File

@@ -0,0 +1,16 @@
#ifndef MUTATE_ENTITY_H
#define MUTATE_ENTITY_H
/* This generated file contains includes for project dependencies */
#include "mutate_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 MUTATE_ENTITY_BAKE_CONFIG_H
#define MUTATE_ENTITY_BAKE_CONFIG_H
/* Headers of public dependencies */
#include <flecs.h>
#endif

View File

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

View File

@@ -0,0 +1,70 @@
#include <mutate_entity.h>
#include <iostream>
#include <iomanip>
struct Timeout {
double value;
};
int main(int, char *[]) {
flecs::world ecs;
// System that deletes an entity after a timeout expires
ecs.system<Timeout>()
.each([](flecs::iter& it, size_t index, Timeout& t) {
t.value -= static_cast<double>(it.delta_time());
if (t.value <= 0) {
// Delete the entity
// To make sure that the storage doesn't change while a system
// is iterating entities, and multiple threads can safely access
// the data, mutations (like a delete) are added to a command
// queue and executed when it's safe to do so.
// When the entity to be mutated is not the same as the entity
// provided by the system, an additional mut() call is required.
// See the mutate_entity_handle example.
flecs::entity e = it.entity(index);
e.destruct();
std::cout << "Expire: " << e.name() << "deleted!\n";
}
});
// System that prints remaining expiry time
ecs.system<const Timeout>()
.each([](flecs::entity e, const Timeout& t) {
std::cout << "PrintExpire: " << e.name() << " has " << std::fixed
<< std::setprecision(2) << t.value << " seconds left\n";
});
// Observer that triggers when entity is actually deleted
ecs.observer<Timeout>()
.event(flecs::OnRemove)
.each([](flecs::entity e, Timeout&) {
std::cout << "Expired: " << e.name() << " actually deleted\n";
});
flecs::entity e = ecs.entity("MyEntity")
.set<Timeout>({3.0});
ecs.set_target_fps(1);
while (ecs.progress()) {
// If entity is no longer alive, exit
if (!e.is_alive()) {
break;
}
std::cout << "Tick...\n";
}
// Output
// PrintExpire: MyEntity has 2.00 seconds left
// Tick...
// PrintExpire: MyEntity has 0.99 seconds left
// Tick...
// Expire: MyEntitydeleted!
// PrintExpire: MyEntity has -0.02 seconds left
// Expired: MyEntity actually deleted
}

View File

@@ -0,0 +1,16 @@
#ifndef MUTATE_ENTITY_HANDLE_H
#define MUTATE_ENTITY_HANDLE_H
/* This generated file contains includes for project dependencies */
#include "mutate_entity_handle/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 MUTATE_ENTITY_HANDLE_BAKE_CONFIG_H
#define MUTATE_ENTITY_HANDLE_BAKE_CONFIG_H
/* Headers of public dependencies */
#include <flecs.h>
#endif

View File

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

View File

@@ -0,0 +1,88 @@
#include <mutate_entity_handle.h>
#include <iostream>
#include <iomanip>
// This example is the same as the mutate_entity example, but instead stores the
// handle of the to be deleted entity in a component.
struct Timeout {
flecs::entity to_delete;
double value;
};
struct Tag { };
int main(int, char *[]) {
flecs::world ecs;
ecs.system<Timeout>()
.each([](flecs::iter& it, size_t, Timeout& t) {
t.value -= static_cast<double>(it.delta_time());
if (t.value <= 0) {
// Delete the entity
// To make sure the delete operation is enqueued (see
// mutate_entity example for more details) we need to provide it
// with a mutable context (stage) using the mut() function. If
// we don't provide a mutable context, the operation will be
// attempted on the context stored in the flecs::entity object,
// which would throw a readonly error.
// To catch these errors at compile time, replace the type of
// to_delete with flecs::entity_view. This class does not have
// any methods for mutating the entity, which forces the code to
// first call mut().
// The it.world() function can be used to provide the context:
// t.to_delete.mut(it.world()).destruct();
//
// The current entity can also be used to provide context. This
// is useful for functions that accept a flecs::entity:
// t.to_delete.mut(it.entity(index)).destruct();
//
// A shortcut is to use the iterator directly:
t.to_delete.mut(it).destruct();
std::cout << "Expire: " << t.to_delete.name() << " deleted!\n";
}
});
ecs.system<const Timeout>()
.each([](const Timeout& t) {
std::cout << "PrintExpire: " << t.to_delete.name() << " has "
<< std::fixed << std::setprecision(2) << t.value
<< " seconds left\n";
});
ecs.observer<Tag>()
.event(flecs::OnRemove)
.each([](flecs::entity e, Tag) {
std::cout << "Expired: " << e.name() << " actually deleted\n";
});
// Add Tag so we can get notified when entity is actually deleted
flecs::entity to_delete = ecs.entity("ToDelete")
.add<Tag>();
ecs.entity("MyEntity")
.set<Timeout>({to_delete, 3.0});
ecs.set_target_fps(1);
while (ecs.progress()) {
// If entity is no longer alive, exit
if (!to_delete.is_alive()) {
break;
}
std::cout << "Tick...\n";
}
// Output
// PrintExpire: ToDelete has 2.00 seconds left
// Tick...
// PrintExpire: ToDelete has 0.98 seconds left
// Tick...
// Expire: ToDelete deleted!
// PrintExpire: ToDelete has -0.03 seconds left
// Expired: ToDelete actually deleted
}

View File

@@ -0,0 +1,16 @@
#ifndef NO_READONLY_H
#define NO_READONLY_H
/* This generated file contains includes for project dependencies */
#include "no_readonly/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 NO_READONLY_BAKE_CONFIG_H
#define NO_READONLY_BAKE_CONFIG_H
/* Headers of public dependencies */
#include <flecs.h>
#endif

View File

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

View File

@@ -0,0 +1,89 @@
#include <no_readonly.h>
#include <iostream>
// When an application calls world.progress(), the world is put in readonly mode.
// This ensures that systems (on multiple threads) can safely iterate
// components, without having to worry about components moving around while
// they're being read. This has as side effect that any operations (like adding
// or removing components) are not visible until the end of the frame (see the
// sync_point example for more details).
// Sometimes this is not what you want, and you need a change to be visible
// immediately. For these use cases, applications can use a no_readonly system.
// This temporarily takes the world out of readonly mode, so a system can make
// changes that are directly visible.
// Because they mutate the world directly, no_readonly systems are never ran on
// more than one thread, and no other systems are ran at the same time.
struct Waiter { };
struct Plate { };
int main(int, char *[]) {
flecs::world ecs;
// Create query to find all waiters without a plate
flecs::query<> q_waiter = ecs.query_builder()
.with<Waiter>()
.without<Plate>(flecs::Wildcard)
.build();
// System that assigns plates to waiter. By making this system no_readonly
// plate assignments are assigned directly (not deferred) to waiters, which
// ensures that we won't assign plates to the same waiter more than once.
ecs.system("AssignPlate")
.with<Plate>()
.without<Waiter>(flecs::Wildcard)
.no_readonly()
.iter([&](flecs::iter& it) {
for (auto i : it) {
flecs::entity plate = it.entity(i);
// Find an available waiter
flecs::entity waiter = q_waiter.first();
if (waiter) {
// An available waiter was found, assign a plate to it so
// that the next plate will no longer find it.
// The defer_suspend function temporarily suspends deferring
// operations, which ensures that our plate is assigned
// immediately. Even though this is a no_readonly system,
// defering is still enabled by default, as adding/removing
// components to the entities being iterated would intefere
// with the system iterator.
it.world().defer_suspend();
waiter.add<Plate>(plate);
it.world().defer_resume();
// Now that defering is resumed, we can safely also add the
// waiter to the plate. We can't do this while defering is
// suspended, because the plate is the entity we're
// currently iterating, and we don't want to move it to a
// different table while we're iterating it.
plate.add<Waiter>(waiter);
std::cout << "Assigned "
<< waiter.name() << " to "
<< plate.name() << "!\n";
} else {
// No available waiters, can't assign the plate
}
}
});
// Create a few plates and waiters
flecs::entity waiter_1 = ecs.entity("waiter_1").add<Waiter>();
ecs.entity("waiter_2").add<Waiter>();
ecs.entity("waiter_3").add<Waiter>();
ecs.entity("plate_1").add<Plate>();
flecs::entity plate_2 = ecs.entity("plate_2").add<Plate>();
ecs.entity("plate_3").add<Plate>();
waiter_1.add<Plate>(plate_2);
plate_2.add<Waiter>(waiter_1);
// run systems
ecs.progress();
// Output:
// Assigned waiter_3 to plate_1!
// Assigned waiter_2 to plate_3!
}

View File

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

View File

@@ -0,0 +1,16 @@
#ifndef PIPELINE_H
#define PIPELINE_H
/* This generated file contains includes for project dependencies */
#include "pipeline/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 PIPELINE_BAKE_CONFIG_H
#define PIPELINE_BAKE_CONFIG_H
/* Headers of public dependencies */
#include <flecs.h>
#endif

View File

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

View File

@@ -0,0 +1,43 @@
#include <pipeline.h>
#include <iostream>
struct Position {
double x, y;
};
struct Velocity {
double x, y;
};
int main(int, char *[]) {
flecs::world ecs;
// Create a system for moving an entity
ecs.system<Position, const Velocity>()
.kind(flecs::OnUpdate) // A phase orders a system in a pipeline
.each([](Position& p, const Velocity& v) {
p.x += v.x;
p.y += v.y;
});
// Create a system for printing the entity position
ecs.system<const Position>()
.kind(flecs::PostUpdate)
.each([](flecs::entity e, const Position& p) {
std::cout << e.name() << ": {" << p.x << ", " << p.y << "}\n";
});
// 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});
// Run the default pipeline. This will run all systems ordered by their
// phase. Systems within the same phase are ran in declaration order. This
// function is usually called in a loop.
ecs.progress();
}

View File

@@ -0,0 +1,16 @@
#ifndef STARTUP_SYSTEM_H
#define STARTUP_SYSTEM_H
/* This generated file contains includes for project dependencies */
#include "startup_system/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 STARTUP_SYSTEM_BAKE_CONFIG_H
#define STARTUP_SYSTEM_BAKE_CONFIG_H
/* Headers of public dependencies */
#include <flecs.h>
#endif

View File

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

View File

@@ -0,0 +1,39 @@
#include <startup_system.h>
#include <iostream>
// Startup systems are systems registered with the EcsOnStart phase, and are
// only ran during the first frame. Just like with regular phases, custom phases
// can depend on the EcsOnStart phase (see custom_phases example). Phases that
// depend on EcsOnStart are also only ran during the first frame.
//
// Other than that, startup systems behave just like regular systems (they can
// match components, can introduce merge points), with as only exception that
// they are guaranteed to always run on the main thread.
int main(int, char *[]) {
flecs::world ecs;
// Startup system
ecs.system("Startup")
.kind(flecs::OnStart)
.iter([](flecs::iter& it) {
std::cout << it.system().name() << "\n";
});
// Regular system
ecs.system("Update")
.iter([](flecs::iter& it) {
std::cout << it.system().name() << "\n";
});
// First frame. This runs both the Startup and Update systems
ecs.progress();
// Second frame. This runs only the Update system
ecs.progress();
// Output
// Startup
// Update
// Update
}

View File

@@ -0,0 +1,16 @@
#ifndef SYNC_POINT_H
#define SYNC_POINT_H
/* This generated file contains includes for project dependencies */
#include "sync_point/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 SYNC_POINT_BAKE_CONFIG_H
#define SYNC_POINT_BAKE_CONFIG_H
/* Headers of public dependencies */
#include <flecs.h>
#endif

View File

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

View File

@@ -0,0 +1,78 @@
#include <sync_point.h>
#include <iostream>
struct Position {
double x, y;
};
struct Velocity {
double x, y;
};
int main(int, char *[]) {
flecs::world ecs;
// System that sets velocity using ecs_set for entities with Position.
// While systems are progressing, operations like ecs_set are deferred until
// it is safe to merge. By default this merge happens at the end of the
// frame, but we can annotate systems to give the scheduler more information
// about what it's doing, which allows it to insert sync points earlier.
//
// Note that sync points are never necessary/inserted for systems that write
// components provided by their signature, as these writes directly happen
// in the ECS storage and are never deferred.
//
// .inout_none() for Position tells the scheduler that while we
// want to match entities with Position, we're not interested in reading or
// writing the component value.
ecs.system("SetVelocity")
.with<Position>().inout_none()
.write<Velocity>() // Velocity is written, but shouldn't be matched
.each([](flecs::entity e) {
e.set<Velocity>({1, 2});
});
// This system reads Velocity, which causes the insertion of a sync point.
ecs.system<Position, const Velocity>("Move")
.each([](Position& p, const Velocity& v) {
p.x += v.x;
p.y += v.y;
});
// Print resulting Position
ecs.system<const Position>("PrintPosition")
.each([](flecs::entity e, const Position& p) {
std::cout << e.name() << ": {" << p.x << ", " << p.y << "}\n";
});
// 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});
// Run systems. Debug logging enables us to see the generated schedule
flecs::log::set_level(1);
ecs.progress();
flecs::log::set_level(-1); // Restore so we don't get world cleanup logs
// Output:
// info: pipeline rebuild:
// info: | schedule: threading: 0, staging: 1:
// info: | | system SetVelocity
// info: | | merge
// info: | schedule: threading: 0, staging: 1:
// info: | | system Move
// info: | | system PrintPosition
// info: | | merge
// e1: {11.000000, 22.000000}
// e2: {11.000000, 22.000000}
//
// The "merge" lines indicate sync points.
//
// Removing '.write<Velocity>()' from the system will remove the first
// sync point from the schedule.
}

View File

@@ -0,0 +1,16 @@
#ifndef SYNC_POINT_DELETE_H
#define SYNC_POINT_DELETE_H
/* This generated file contains includes for project dependencies */
#include "sync_point_delete/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 SYNC_POINT_DELETE_BAKE_CONFIG_H
#define SYNC_POINT_DELETE_BAKE_CONFIG_H
/* Headers of public dependencies */
#include <flecs.h>
#endif

View File

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

View File

@@ -0,0 +1,97 @@
#include <sync_point_delete.h>
#include <iostream>
struct Position {
double x, y;
};
struct Velocity {
double x, y;
};
int main(int, char *[]) {
flecs::world ecs;
// This example shows how to annotate systems that delete entities, in a way
// that allows the scheduler to correctly insert sync points. See the
// sync_point example for more details on sync points.
//
// While annotating a system for a delete operation follows the same
// design as other operations, one key difference is that a system often
// does not know which components a to be deleted entity has. This makes it
// impossible to annotate the system in advance for specific components.
//
// To ensure the scheduler is still able to insert the correct sync points,
// a system can use a wildcard to indicate that any component could be
// modified by the system, which forces the scheduler to insert a sync.
// Basic move system.
ecs.system<Position, const Velocity>("Move")
.each([](Position& p, const Velocity& v) {
p.x += v.x;
p.y += v.y;
});
// Delete entities when p.x >= 3. Add wildcard annotation to indicate any
// component could be written by the system. Position itself is added as
// const, since inside the system we're only reading it.
ecs.system<const Position>("DeleteEntity")
.write(flecs::Wildcard)
.each([](flecs::entity e, const Position& p) {
if (p.x >= 3) {
std::cout << "Delete entity " << e.name() << "\n";
e.destruct();
}
});
// Print resulting Position. Note that this system will never print entities
// that have been deleted by the previous system.
ecs.system<const Position>("PrintPosition")
.each([](flecs::entity e, const Position& p) {
std::cout << e.name() << ": {" << p.x << ", " << p.y << "}\n";
});
// Create a few test entities for a Position, Velocity query
ecs.entity("e1")
.set<Position>({0, 0})
.set<Velocity>({1, 2});
ecs.entity("e2")
.set<Position>({1, 2})
.set<Velocity>({1, 2});
// Run systems. Debug logging enables us to see the generated schedule
flecs::log::set_level(1);
while (ecs.progress()) {
if (!ecs.count<Position>()) {
break; // No more entities left with Position
}
}
flecs::log::set_level(-1); // Restore so we don't get world cleanup logs
// Output:
// info: pipeline rebuild:
// info: | schedule: threading: 0, staging: 1:
// info: | | system Move
// info: | | system DeleteEntity
// info: | | merge
// info: | schedule: threading: 0, staging: 1:
// info: | | system PrintPosition
// info: | | merge
// e1: {1, 2}
// e2: {2, 4}
// Delete entity e2
// e1: {2, 4}
// Delete entity e1
// info: system Move deactivated
// info: system DeleteEntity deactivated
// info: system PrintPosition deactivated
//
// Removing the wildcard annotation from the DeleteEntity system will
// remove the first sync point.
//
// Note how after both entities are deleted, all three systems are
// deactivated. This happens when there are no matching entities for a
// system. A deactivated system is not ran by the scheduler, which reduces
// overhead.
}

View File

@@ -0,0 +1,16 @@
#ifndef SYSTEM_CTX_H
#define SYSTEM_CTX_H
/* This generated file contains includes for project dependencies */
#include "system_ctx/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 SYSTEM_CTX_BAKE_CONFIG_H
#define SYSTEM_CTX_BAKE_CONFIG_H
/* Headers of public dependencies */
#include <flecs.h>
#endif

View File

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

View File

@@ -0,0 +1,78 @@
#include <system_ctx.h>
#include <iostream>
// Applications can pass context data to a system. A common use case where this
// comes in handy is when a system needs to iterate more than one query. The
// following example shows how to pass a custom query into a system for a simple
// collision detection example.
struct Position {
double x, y;
};
struct Radius {
double value;
};
double sqr(double value) {
return value * value;
}
double distance_sqr(const Position& p1, const Position& p2) {
return sqr(p2.x - p1.x) + sqr(p2.y - p1.y);
}
double randd(int max) {
return static_cast<double>((rand() % max));
}
using CollisionQuery = flecs::query<const Position, const Radius>;
int main(int, char *[]) {
flecs::world ecs;
CollisionQuery q_collide = ecs.query<const Position, const Radius>();
flecs::system sys = ecs.system<const Position, const Radius>("Collide")
.ctx(&q_collide)
.each([](flecs::iter& it, size_t i, const Position& p1, const Radius& r1) {
CollisionQuery *q = it.ctx<CollisionQuery>();
flecs::entity e1 = it.entity(i);
q->each([&](flecs::entity e2, const Position& p2, const Radius& r2) {
if (e1 == e2) {
// don't collide with self
return;
}
if (e1 > e2) {
// Simple trick to prevent collisions from being detected
// twice with the entities reversed.
return;
}
// Check for collision
double d_sqr = distance_sqr(p1, p2);
double r_sqr = sqr(r1.value + r2.value);
if (r_sqr > d_sqr) {
std::cout << e1 << " and " << e2 << " collided!\n";
}
});
});
// Create a few test entities
for (int i = 0; i < 10; i ++) {
ecs.entity()
.set<Position>({ randd(100), randd(100) })
.set<Radius>({ randd(10) + 1 });
}
// Run the system
sys.run();
// Output
// 526 and 529 collided!
// 527 and 534 collided!
// 529 and 531 collided!
// 533 and 535 collided!
}

View File

@@ -0,0 +1,16 @@
#ifndef TARGET_FPS_H
#define TARGET_FPS_H
/* This generated file contains includes for project dependencies */
#include "target_fps/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 TARGET_FPS_BAKE_CONFIG_H
#define TARGET_FPS_BAKE_CONFIG_H
/* Headers of public dependencies */
#include <flecs.h>
#endif

View File

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

View File

@@ -0,0 +1,33 @@
#include <target_fps.h>
#include <iostream>
int main(int, char *[]) {
flecs::world ecs;
// Create system that prints delta_time. This system doesn't query for any
// components which means it won't match any entities, but will still be ran
// once for each call to ecs_progress.
ecs.system()
.iter([](flecs::iter& it) {
std::cout << "delta_time: " << it.delta_time() << std::endl;
});
// Set target FPS to 1 frame per second
ecs.set_target_fps(1);
// Run 5 frames
for (int i = 0; i < 5; i ++) {
// To make sure the frame doesn't run faster than the specified target
// FPS ecs_progress will insert a sleep if the measured delta_time is
// smaller than 1 / target_fps.
//
// By default ecs_progress uses the sleep function provided by the OS
// which is not always very accurate. If more accuracy is required the
// sleep function of the OS API can be overridden with a custom one.
//
// If a value other than 0 is provided to the delta_time argument of
// ecs_progress, this value will be used to calculate the length of
// the sleep to insert.
ecs.progress();
}
}

View File

@@ -0,0 +1,16 @@
#ifndef TIME_INTERVAL_H
#define TIME_INTERVAL_H
/* This generated file contains includes for project dependencies */
#include "time_interval/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 TIME_INTERVAL_BAKE_CONFIG_H
#define TIME_INTERVAL_BAKE_CONFIG_H
/* Headers of public dependencies */
#include <flecs.h>
#endif

View File

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

View File

@@ -0,0 +1,38 @@
#include <time_interval.h>
#include <iostream>
// This example shows how to run a system at a specified time interval.
void Tick(flecs::iter& it) {
std::cout << it.system().name() << "\n";
}
int main(int, char *[]) {
flecs::world ecs;
ecs.system("Tick")
.interval(1.0) // time in seconds
.iter(Tick);
ecs.system("FastTick")
.interval(0.5)
.iter(Tick);
// Run the main loop at 60 FPS
ecs.set_target_fps(60);
while (ecs.progress()) { }
// Output
// FastTick
// Tick
// FastTick
// FastTick
// Tick
// FastTick
// FastTick
// Tick
// FastTick
// FastTick
// ...
}