Properly link flecs library
This commit is contained in:
4
engine/libs/flecs/test/addons/.gitignore
vendored
Normal file
4
engine/libs/flecs/test/addons/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
.bake_cache
|
||||
.DS_Store
|
||||
.vscode
|
||||
bin
|
||||
115
engine/libs/flecs/test/addons/include/addons.h
Normal file
115
engine/libs/flecs/test/addons/include/addons.h
Normal file
@@ -0,0 +1,115 @@
|
||||
#ifndef ADDONS_H
|
||||
#define ADDONS_H
|
||||
|
||||
/* This generated file contains includes for project dependencies */
|
||||
#include <addons/bake_config.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MAX_SYS_COLUMNS (20)
|
||||
#define MAX_ENTITIES (256)
|
||||
#define MAX_INVOCATIONS (1024)
|
||||
|
||||
/* Multiline strings */
|
||||
#define HEAD
|
||||
#define LINE "\n"
|
||||
|
||||
typedef struct Probe {
|
||||
ecs_entity_t system;
|
||||
ecs_entity_t event;
|
||||
ecs_id_t event_id;
|
||||
int32_t offset;
|
||||
int32_t count;
|
||||
int32_t invoked;
|
||||
int32_t term_count;
|
||||
int32_t term_index;
|
||||
ecs_entity_t e[MAX_ENTITIES];
|
||||
ecs_entity_t c[MAX_INVOCATIONS][MAX_SYS_COLUMNS];
|
||||
ecs_entity_t s[MAX_INVOCATIONS][MAX_SYS_COLUMNS];
|
||||
void *param;
|
||||
} Probe;
|
||||
|
||||
typedef struct IterData {
|
||||
ecs_entity_t component;
|
||||
ecs_entity_t component_2;
|
||||
ecs_entity_t component_3;
|
||||
ecs_entity_t new_entities[MAX_ENTITIES];
|
||||
int32_t entity_count;
|
||||
} IterData;
|
||||
|
||||
typedef struct Position {
|
||||
float x;
|
||||
float y;
|
||||
} Position;
|
||||
|
||||
typedef struct Velocity {
|
||||
float x;
|
||||
float y;
|
||||
} Velocity;
|
||||
|
||||
typedef float Mass;
|
||||
|
||||
typedef float Rotation;
|
||||
|
||||
typedef struct Color {
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
float a;
|
||||
} Color;
|
||||
|
||||
typedef struct Self {
|
||||
ecs_entity_t value;
|
||||
} Self;
|
||||
|
||||
void probe_system_w_ctx(
|
||||
ecs_iter_t *it,
|
||||
Probe *ctx);
|
||||
|
||||
void probe_iter(ecs_iter_t *it);
|
||||
|
||||
void probe_has_entity(Probe *probe, ecs_entity_t e);
|
||||
|
||||
void install_test_abort(void);
|
||||
|
||||
#define ITER_MAX_ENTITIES (64)
|
||||
#define ITER_MAX_TERMS (16)
|
||||
#define ITER_MAX_VARIABLES (16)
|
||||
|
||||
typedef struct test_iter_result_t {
|
||||
ecs_entity_t entities[ITER_MAX_ENTITIES];
|
||||
ecs_id_t term_ids[ITER_MAX_ENTITIES][ITER_MAX_TERMS];
|
||||
void *term_columns[ITER_MAX_TERMS];
|
||||
|
||||
int32_t table_count_expect;
|
||||
int32_t table_count_actual;
|
||||
|
||||
char *entity_names[ITER_MAX_ENTITIES];
|
||||
char *term_ids_expr[ITER_MAX_ENTITIES][ITER_MAX_TERMS];
|
||||
int32_t matched[ITER_MAX_ENTITIES];
|
||||
|
||||
struct {
|
||||
int32_t id;
|
||||
ecs_entity_t entities[ITER_MAX_ENTITIES];
|
||||
char *entity_names[ITER_MAX_ENTITIES];
|
||||
} variables[ITER_MAX_VARIABLES];
|
||||
} test_iter_result_t;
|
||||
|
||||
// Utility for doing order-independent validation of iterator output
|
||||
bool test_iter(
|
||||
ecs_iter_t *it,
|
||||
ecs_iter_next_action_t next,
|
||||
test_iter_result_t *expect);
|
||||
|
||||
const ecs_entity_t* bulk_new_w_type(
|
||||
ecs_world_t *world, ecs_entity_t type_ent, int32_t count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
25
engine/libs/flecs/test/addons/include/addons/bake_config.h
Normal file
25
engine/libs/flecs/test/addons/include/addons/bake_config.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
)
|
||||
(.)
|
||||
.|.
|
||||
| |
|
||||
_.--| |--._
|
||||
.-'; ;`-'& ; `&.
|
||||
\ & ; & &_/
|
||||
|"""---...---"""|
|
||||
\ | | | | | | | /
|
||||
`---.|.|.|.---'
|
||||
|
||||
* 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 ADDONS_BAKE_CONFIG_H
|
||||
#define ADDONS_BAKE_CONFIG_H
|
||||
|
||||
/* Headers of public dependencies */
|
||||
#include <flecs.h>
|
||||
#include <bake_test.h>
|
||||
|
||||
#endif
|
||||
|
||||
1675
engine/libs/flecs/test/addons/project.json
Normal file
1675
engine/libs/flecs/test/addons/project.json
Normal file
File diff suppressed because it is too large
Load Diff
2587
engine/libs/flecs/test/addons/src/Alerts.c
Normal file
2587
engine/libs/flecs/test/addons/src/Alerts.c
Normal file
File diff suppressed because it is too large
Load Diff
115
engine/libs/flecs/test/addons/src/App.c
Normal file
115
engine/libs/flecs/test/addons/src/App.c
Normal file
@@ -0,0 +1,115 @@
|
||||
#include <addons.h>
|
||||
|
||||
static int dummy_frame_action(
|
||||
ecs_world_t *world,
|
||||
const ecs_app_desc_t *desc)
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
void App_app_w_frame_action(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
test_int(ecs_app_set_frame_action(dummy_frame_action), 0);
|
||||
|
||||
int result = ecs_app_run(world, &(ecs_app_desc_t){ 0 });
|
||||
test_int(result, 10);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static void Sys(ecs_iter_t *it) {
|
||||
ecs_quit(it->world);
|
||||
}
|
||||
|
||||
void App_app_w_default_frame_action(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_SYSTEM(world, Sys, EcsOnUpdate, 0);
|
||||
|
||||
int result = ecs_app_run(world, &(ecs_app_desc_t){ 0 });
|
||||
test_int(result, 0);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static
|
||||
void Dummy(ecs_iter_t *it) {
|
||||
ecs_quit(it->world);
|
||||
}
|
||||
|
||||
void App_app_w_set_threads(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_SYSTEM(world, Dummy, EcsOnUpdate, 0);
|
||||
|
||||
test_int(ecs_get_stage_count(world), 1);
|
||||
|
||||
ecs_set_threads(world, 2);
|
||||
|
||||
test_int(ecs_get_stage_count(world), 2);
|
||||
|
||||
ecs_app_run(world, &(ecs_app_desc_t) { 0 });
|
||||
|
||||
test_int(ecs_get_stage_count(world), 2);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void App_app_w_set_task_threads(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_SYSTEM(world, Dummy, EcsOnUpdate, 0);
|
||||
|
||||
test_int(ecs_get_stage_count(world), 1);
|
||||
|
||||
ecs_set_task_threads(world, 2);
|
||||
|
||||
test_int(ecs_get_stage_count(world), 2);
|
||||
|
||||
ecs_app_run(world, &(ecs_app_desc_t) { 0 });
|
||||
|
||||
test_int(ecs_get_stage_count(world), 2);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void App_app_w_set_target_fps(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_SYSTEM(world, Dummy, EcsOnUpdate, 0);
|
||||
|
||||
const ecs_world_info_t *info = ecs_get_world_info(world);
|
||||
|
||||
test_int(info->target_fps, 0);
|
||||
|
||||
ecs_set_target_fps(world, 60);
|
||||
|
||||
test_int(info->target_fps, 60);
|
||||
|
||||
ecs_app_run(world, &(ecs_app_desc_t) { 0 });
|
||||
|
||||
test_int(info->target_fps, 60);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static int sys_invoked = 0;
|
||||
|
||||
static void SysCount(ecs_iter_t *it) {
|
||||
sys_invoked ++;
|
||||
}
|
||||
|
||||
void App_app_w_set_frames(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_SYSTEM(world, SysCount, EcsOnUpdate, 0);
|
||||
|
||||
ecs_app_run(world, &(ecs_app_desc_t) {
|
||||
.frames = 100
|
||||
});
|
||||
|
||||
test_int(sys_invoked, 100);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
134
engine/libs/flecs/test/addons/src/Doc.c
Normal file
134
engine/libs/flecs/test/addons/src/Doc.c
Normal file
@@ -0,0 +1,134 @@
|
||||
#include <addons.h>
|
||||
|
||||
void Doc_get_set_name(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_entity_t e = ecs_new_id(world);
|
||||
|
||||
ecs_doc_set_name(world, e, "Human readable name");
|
||||
|
||||
test_assert( ecs_has_pair(world, e, ecs_id(EcsDocDescription), EcsName));
|
||||
test_str( ecs_doc_get_name(world, e), "Human readable name");
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Doc_get_entity_name(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_entity_t e = ecs_set_name(world, 0, "Entity name");
|
||||
|
||||
test_assert( ecs_has_pair(world, e, ecs_id(EcsIdentifier), EcsName));
|
||||
test_str( ecs_doc_get_name(world, e), "Entity name");
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Doc_get_set_brief(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, MyTag);
|
||||
|
||||
ecs_doc_set_brief(world, MyTag, "Brief description");
|
||||
|
||||
test_assert( ecs_has_pair(world, MyTag, ecs_id(EcsDocDescription), EcsDocBrief));
|
||||
test_str( ecs_doc_get_brief(world, MyTag), "Brief description");
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Doc_get_set_detail(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, MyTag);
|
||||
|
||||
ecs_doc_set_detail(world, MyTag, "Detailed description");
|
||||
|
||||
test_assert( ecs_has_pair(world, MyTag, ecs_id(EcsDocDescription), EcsDocDetail));
|
||||
test_str( ecs_doc_get_detail(world, MyTag), "Detailed description");
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Doc_get_set_link(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, MyTag);
|
||||
|
||||
ecs_doc_set_link(world, MyTag, "http://www.example.com");
|
||||
|
||||
test_assert( ecs_has_pair(world, MyTag, ecs_id(EcsDocDescription), EcsDocLink));
|
||||
test_str( ecs_doc_get_link(world, MyTag), "http://www.example.com");
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Doc_set_name_nullptr(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_entity_t e = ecs_new_id(world);
|
||||
|
||||
ecs_doc_set_name(world, e, "foo");
|
||||
test_assert( ecs_has_pair(world, e, ecs_id(EcsDocDescription), EcsName));
|
||||
|
||||
ecs_doc_set_name(world, e, NULL);
|
||||
test_assert( !ecs_has_pair(world, e, ecs_id(EcsDocDescription), EcsName));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Doc_set_brief_nullptr(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_entity_t e = ecs_new_id(world);
|
||||
|
||||
ecs_doc_set_brief(world, e, "foo");
|
||||
test_assert( ecs_has_pair(world, e, ecs_id(EcsDocDescription), EcsDocBrief));
|
||||
|
||||
ecs_doc_set_brief(world, e, NULL);
|
||||
test_assert( !ecs_has_pair(world, e, ecs_id(EcsDocDescription), EcsDocBrief));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Doc_set_detail_nullptr(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_entity_t e = ecs_new_id(world);
|
||||
|
||||
ecs_doc_set_detail(world, e, "foo");
|
||||
test_assert( ecs_has_pair(world, e, ecs_id(EcsDocDescription), EcsDocDetail));
|
||||
|
||||
ecs_doc_set_detail(world, e, NULL);
|
||||
test_assert( !ecs_has_pair(world, e, ecs_id(EcsDocDescription), EcsDocDetail));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Doc_set_link_nullptr(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_entity_t e = ecs_new_id(world);
|
||||
|
||||
ecs_doc_set_link(world, e, "foo");
|
||||
test_assert( ecs_has_pair(world, e, ecs_id(EcsDocDescription), EcsDocLink));
|
||||
|
||||
ecs_doc_set_link(world, e, NULL);
|
||||
test_assert( !ecs_has_pair(world, e, ecs_id(EcsDocDescription), EcsDocLink));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Doc_set_color_nullptr(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_entity_t e = ecs_new_id(world);
|
||||
|
||||
ecs_doc_set_color(world, e, "foo");
|
||||
test_assert( ecs_has_pair(world, e, ecs_id(EcsDocDescription), EcsDocColor));
|
||||
|
||||
ecs_doc_set_color(world, e, NULL);
|
||||
test_assert( !ecs_has_pair(world, e, ecs_id(EcsDocDescription), EcsDocColor));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
70
engine/libs/flecs/test/addons/src/Http.c
Normal file
70
engine/libs/flecs/test/addons/src/Http.c
Normal file
@@ -0,0 +1,70 @@
|
||||
#include <addons.h>
|
||||
|
||||
static bool OnRequest(
|
||||
const ecs_http_request_t* request,
|
||||
ecs_http_reply_t *reply,
|
||||
void *ctx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void Http_teardown(void) {
|
||||
ecs_set_os_api_impl();
|
||||
|
||||
ecs_http_server_t *srv = ecs_http_server_init(&(ecs_http_server_desc_t){
|
||||
.port = 27750,
|
||||
.callback = OnRequest
|
||||
});
|
||||
|
||||
test_assert(srv != NULL);
|
||||
|
||||
ecs_http_server_fini(srv);
|
||||
}
|
||||
|
||||
void Http_teardown_started(void) {
|
||||
ecs_set_os_api_impl();
|
||||
|
||||
ecs_http_server_t *srv = ecs_http_server_init(&(ecs_http_server_desc_t){
|
||||
.port = 27751,
|
||||
.callback = OnRequest
|
||||
});
|
||||
|
||||
test_assert(srv != NULL);
|
||||
|
||||
test_int(ecs_http_server_start(srv), 0);
|
||||
|
||||
ecs_http_server_fini(srv);
|
||||
}
|
||||
|
||||
void Http_teardown_stopped(void) {
|
||||
ecs_set_os_api_impl();
|
||||
|
||||
ecs_http_server_t *srv = ecs_http_server_init(&(ecs_http_server_desc_t){
|
||||
.port = 27752,
|
||||
.callback = OnRequest
|
||||
});
|
||||
|
||||
test_assert(srv != NULL);
|
||||
|
||||
test_int(ecs_http_server_start(srv), 0);
|
||||
ecs_http_server_stop(srv);
|
||||
|
||||
ecs_http_server_fini(srv);
|
||||
}
|
||||
|
||||
void Http_stop_start(void) {
|
||||
ecs_set_os_api_impl();
|
||||
|
||||
ecs_http_server_t *srv = ecs_http_server_init(&(ecs_http_server_desc_t){
|
||||
.port = 27753,
|
||||
.callback = OnRequest
|
||||
});
|
||||
|
||||
test_assert(srv != NULL);
|
||||
|
||||
test_int(ecs_http_server_start(srv), 0);
|
||||
ecs_http_server_stop(srv);
|
||||
test_int(ecs_http_server_start(srv), 0);
|
||||
|
||||
ecs_http_server_fini(srv);
|
||||
}
|
||||
2419
engine/libs/flecs/test/addons/src/Metrics.c
Normal file
2419
engine/libs/flecs/test/addons/src/Metrics.c
Normal file
File diff suppressed because it is too large
Load Diff
412
engine/libs/flecs/test/addons/src/Modules.c
Normal file
412
engine/libs/flecs/test/addons/src/Modules.c
Normal file
@@ -0,0 +1,412 @@
|
||||
#include <addons.h>
|
||||
|
||||
void Modules_setup(void) {
|
||||
}
|
||||
|
||||
/* -- Begin module code -- */
|
||||
|
||||
typedef struct SimpleFooComponent {
|
||||
float value;
|
||||
} SimpleFooComponent;
|
||||
|
||||
typedef struct NestedComponent {
|
||||
float value;
|
||||
} NestedComponent;
|
||||
|
||||
static
|
||||
void Move(ecs_iter_t *it) { }
|
||||
|
||||
static
|
||||
void SimpleFooSystem(ecs_iter_t *it) { }
|
||||
|
||||
static
|
||||
void SimpleFooTrigger(ecs_iter_t *it) { }
|
||||
|
||||
static ECS_COMPONENT_DECLARE(NestedComponent);
|
||||
|
||||
static ECS_COMPONENT_DECLARE(Position);
|
||||
static ECS_COMPONENT_DECLARE(Velocity);
|
||||
static ECS_COMPONENT_DECLARE(SimpleFooComponent);
|
||||
static ECS_DECLARE(Tag);
|
||||
static ECS_DECLARE(SimpleFooTag);
|
||||
static ECS_DECLARE(Entity);
|
||||
static ECS_DECLARE(SimpleFooEntity);
|
||||
static ECS_DECLARE(SimpleFooPrefab);
|
||||
static ECS_DECLARE(SimpleFooPipeline);
|
||||
static ECS_DECLARE(Simple_underscore);
|
||||
|
||||
static ECS_SYSTEM_DECLARE(Move);
|
||||
static ECS_SYSTEM_DECLARE(SimpleFooSystem);
|
||||
static ECS_SYSTEM_DECLARE(SimpleFooTrigger);
|
||||
|
||||
void NestedModuleImport(
|
||||
ecs_world_t *world)
|
||||
{
|
||||
ECS_MODULE(world, NestedModule);
|
||||
|
||||
ecs_set_name_prefix(world, "Nested");
|
||||
|
||||
ECS_COMPONENT_DEFINE(world, NestedComponent);
|
||||
}
|
||||
|
||||
void SimpleModuleImport(
|
||||
ecs_world_t *world)
|
||||
{
|
||||
ECS_MODULE(world, SimpleModule);
|
||||
|
||||
ECS_IMPORT(world, NestedModule);
|
||||
|
||||
ecs_set_name_prefix(world, "Simple");
|
||||
|
||||
ECS_COMPONENT_DEFINE(world, Position);
|
||||
ECS_COMPONENT_DEFINE(world, Velocity);
|
||||
ECS_COMPONENT_DEFINE(world, SimpleFooComponent);
|
||||
|
||||
ECS_TAG_DEFINE(world, Tag);
|
||||
ECS_ENTITY_DEFINE(world, Entity, 0);
|
||||
|
||||
ECS_SYSTEM_DEFINE(world, Move, EcsOnUpdate, Position, Velocity);
|
||||
ECS_SYSTEM_DEFINE(world, SimpleFooSystem, EcsOnUpdate, Position);
|
||||
ECS_OBSERVER_DEFINE(world, SimpleFooTrigger, EcsOnAdd, Position);
|
||||
|
||||
ECS_TAG_DEFINE(world, SimpleFooTag);
|
||||
ECS_ENTITY_DEFINE(world, SimpleFooEntity, 0);
|
||||
ECS_PREFAB_DEFINE(world, SimpleFooPrefab, 0);
|
||||
ECS_PIPELINE_DEFINE(world, SimpleFooPipeline, flecs.system.System, Tag);
|
||||
ECS_TAG_DEFINE(world, Simple_underscore);
|
||||
}
|
||||
|
||||
/* -- End module code -- */
|
||||
|
||||
void Modules_simple_module(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_IMPORT(world, SimpleModule);
|
||||
|
||||
ecs_entity_t e = ecs_new(world, Position);
|
||||
test_assert(e != 0);
|
||||
test_assert( ecs_has(world, e, Position));
|
||||
|
||||
ecs_add(world, e, Velocity);
|
||||
test_assert( ecs_has(world, e, Velocity));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static
|
||||
void AddVtoP(ecs_iter_t *it) {
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
ecs_add(it->world, it->entities[i], Velocity);
|
||||
}
|
||||
}
|
||||
|
||||
void Modules_import_module_from_system(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_IMPORT(world, SimpleModule);
|
||||
ECS_SYSTEM(world, AddVtoP, EcsOnUpdate, simple.module.Position);
|
||||
|
||||
ecs_entity_t e = ecs_new(world, Position);
|
||||
test_assert(e != 0);
|
||||
test_assert( ecs_has(world, e, Position));
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_assert( ecs_has(world, e, Velocity));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Modules_import_again(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_entity_t m1 = ECS_IMPORT(world, SimpleModule);
|
||||
ecs_entity_t m2 = ECS_IMPORT(world, SimpleModule);
|
||||
|
||||
test_assert(m1 != 0);
|
||||
test_assert(m2 != 0);
|
||||
test_assert(m1 == m2);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Modules_scoped_component(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_IMPORT(world, SimpleModule);
|
||||
|
||||
ecs_entity_t e = ecs_lookup_fullpath(world, "simple.module.Position");
|
||||
test_assert(e != 0);
|
||||
test_assert(e == ecs_id(Position));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Modules_scoped_tag(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_IMPORT(world, SimpleModule);
|
||||
|
||||
ecs_entity_t e = ecs_lookup_fullpath(world, "simple.module.Tag");
|
||||
test_assert(e != 0);
|
||||
test_assert(e == Tag);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Modules_scoped_system(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_IMPORT(world, SimpleModule);
|
||||
|
||||
ecs_entity_t e = ecs_lookup_fullpath(world, "simple.module.Move");
|
||||
test_assert(e != 0);
|
||||
test_assert(e == ecs_id(Move));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Modules_scoped_entity(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_IMPORT(world, SimpleModule);
|
||||
|
||||
ecs_entity_t e = ecs_lookup_fullpath(world, "simple.module.Entity");
|
||||
test_assert(e != 0);
|
||||
test_assert(e == Entity);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Modules_name_prefix_component(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_IMPORT(world, SimpleModule);
|
||||
|
||||
ecs_entity_t e = ecs_lookup_fullpath(world, "simple.module.FooComponent");
|
||||
test_assert(e != 0);
|
||||
test_assert(e == ecs_id(SimpleFooComponent));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Modules_name_prefix_tag(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_IMPORT(world, SimpleModule);
|
||||
|
||||
ecs_entity_t e = ecs_lookup_fullpath(world, "simple.module.FooTag");
|
||||
test_assert(e != 0);
|
||||
test_assert(e == SimpleFooTag);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Modules_name_prefix_system(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_IMPORT(world, SimpleModule);
|
||||
|
||||
ecs_entity_t e = ecs_lookup_fullpath(world, "simple.module.FooSystem");
|
||||
test_assert(e != 0);
|
||||
test_assert(e == ecs_id(SimpleFooSystem));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Modules_name_prefix_entity(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_IMPORT(world, SimpleModule);
|
||||
|
||||
ecs_entity_t e = ecs_lookup_fullpath(world, "simple.module.FooEntity");
|
||||
test_assert(e != 0);
|
||||
test_assert(e == SimpleFooEntity);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Modules_name_prefix_prefab(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_IMPORT(world, SimpleModule);
|
||||
|
||||
ecs_entity_t e = ecs_lookup_fullpath(world, "simple.module.FooPrefab");
|
||||
test_assert(e != 0);
|
||||
test_assert(e == SimpleFooPrefab);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Modules_name_prefix_pipeline(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_IMPORT(world, SimpleModule);
|
||||
|
||||
ecs_entity_t e = ecs_lookup_fullpath(world, "simple.module.FooPipeline");
|
||||
test_assert(e != 0);
|
||||
test_assert(e == SimpleFooPipeline);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Modules_name_prefix_trigger(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_IMPORT(world, SimpleModule);
|
||||
|
||||
ecs_entity_t e = ecs_lookup_fullpath(world, "simple.module.FooTrigger");
|
||||
test_assert(e != 0);
|
||||
test_assert(e == ecs_id(SimpleFooTrigger));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Modules_name_prefix_underscore(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_IMPORT(world, SimpleModule);
|
||||
|
||||
ecs_entity_t e = ecs_lookup_fullpath(world, "simple.module.underscore");
|
||||
test_assert(e != 0);
|
||||
test_assert(e == Simple_underscore);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Modules_lookup_by_symbol(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_IMPORT(world, SimpleModule);
|
||||
|
||||
ecs_entity_t e = ecs_lookup_symbol(world, "Position", true, true);
|
||||
test_assert(e != 0);
|
||||
test_assert(e == ecs_id(Position));
|
||||
|
||||
e = ecs_lookup_symbol(world, "SimpleFooComponent", true, true);
|
||||
test_assert(e != 0);
|
||||
test_assert(e == ecs_id(SimpleFooComponent));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Modules_nested_module(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_IMPORT(world, SimpleModule);
|
||||
|
||||
ecs_entity_t e = ecs_lookup_fullpath(world, "nested.module.Component");
|
||||
test_assert(e != 0);
|
||||
|
||||
char *path = ecs_get_fullpath(world, e);
|
||||
test_str(path, "nested.module.Component");
|
||||
ecs_os_free(path);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Modules_module_tag_on_namespace(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_IMPORT(world, SimpleModule);
|
||||
|
||||
ecs_entity_t mid = ecs_lookup_fullpath(world, "simple.module");
|
||||
test_assert(mid != 0);
|
||||
test_assert(ecs_has_id(world, mid, EcsModule));
|
||||
|
||||
ecs_entity_t nid = ecs_lookup_fullpath(world, "simple");
|
||||
test_assert(nid != 0);
|
||||
test_assert(ecs_has_id(world, nid, EcsModule));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Modules_module_tag_on_namespace_on_add(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_entity_t parent = ecs_new_id(world);
|
||||
test_assert(parent != 0);
|
||||
|
||||
ecs_entity_t child = ecs_new_w_pair(world, EcsChildOf, parent);
|
||||
test_assert(child != 0);
|
||||
|
||||
ecs_add_id(world, child, EcsModule);
|
||||
test_assert( ecs_has_id(world, child, EcsModule));
|
||||
test_assert( ecs_has_id(world, parent, EcsModule));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Modules_module_tag_on_namespace_on_add_2_levels(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_entity_t root = ecs_new_id(world);
|
||||
test_assert(root != 0);
|
||||
|
||||
ecs_entity_t parent = ecs_new_w_pair(world, EcsChildOf, root);
|
||||
test_assert(parent != 0);
|
||||
|
||||
ecs_entity_t child = ecs_new_w_pair(world, EcsChildOf, parent);
|
||||
test_assert(child != 0);
|
||||
|
||||
ecs_add_id(world, child, EcsModule);
|
||||
test_assert( ecs_has_id(world, child, EcsModule));
|
||||
test_assert( ecs_has_id(world, parent, EcsModule));
|
||||
test_assert( ecs_has_id(world, root, EcsModule));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Modules_import_2_worlds(void) {
|
||||
ecs_world_t *world_1 = ecs_init();
|
||||
ecs_world_t *world_2 = ecs_init();
|
||||
|
||||
ECS_IMPORT(world_1, SimpleModule);
|
||||
ECS_IMPORT(world_2, SimpleModule);
|
||||
|
||||
test_assert(ecs_lookup_fullpath(world_1, "simple.module") != 0);
|
||||
test_assert(ecs_lookup_fullpath(world_2, "simple.module") != 0);
|
||||
|
||||
{
|
||||
ecs_entity_t e = ecs_new(world_1, Position);
|
||||
test_assert(e != 0);
|
||||
test_assert( ecs_has(world_1, e, Position));
|
||||
ecs_add(world_1, e, Velocity);
|
||||
test_assert( ecs_has(world_1, e, Velocity));
|
||||
}
|
||||
{
|
||||
ecs_entity_t e = ecs_new(world_2, Position);
|
||||
test_assert(e != 0);
|
||||
test_assert( ecs_has(world_2, e, Position));
|
||||
ecs_add(world_2, e, Velocity);
|
||||
test_assert( ecs_has(world_2, e, Velocity));
|
||||
}
|
||||
|
||||
ecs_fini(world_1);
|
||||
ecs_fini(world_2);
|
||||
}
|
||||
|
||||
void Modules_import_monitor_2_worlds(void) {
|
||||
ecs_world_t *world_1 = ecs_init();
|
||||
ecs_world_t *world_2 = ecs_init();
|
||||
|
||||
ECS_IMPORT(world_1, FlecsMonitor);
|
||||
ECS_IMPORT(world_2, FlecsMonitor);
|
||||
|
||||
test_assert(ecs_exists(world_1, ecs_id(FlecsMonitor)));
|
||||
test_assert(ecs_exists(world_2, ecs_id(FlecsMonitor)));
|
||||
|
||||
ecs_fini(world_1);
|
||||
ecs_fini(world_2);
|
||||
}
|
||||
|
||||
void Modules_import_monitor_after_mini(void) {
|
||||
ecs_world_t *world = ecs_mini();
|
||||
|
||||
ECS_IMPORT(world, FlecsMonitor);
|
||||
|
||||
test_assert(ecs_exists(world, ecs_id(FlecsMonitor)));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
1384
engine/libs/flecs/test/addons/src/MultiTaskThread.c
Normal file
1384
engine/libs/flecs/test/addons/src/MultiTaskThread.c
Normal file
File diff suppressed because it is too large
Load Diff
613
engine/libs/flecs/test/addons/src/MultiTaskThreadStaging.c
Normal file
613
engine/libs/flecs/test/addons/src/MultiTaskThreadStaging.c
Normal file
@@ -0,0 +1,613 @@
|
||||
#include <addons.h>
|
||||
|
||||
void MultiTaskThreadStaging_setup(void) {
|
||||
ecs_log_set_level(-3);
|
||||
}
|
||||
|
||||
static
|
||||
void MultiTaskThread_Add_to_current(ecs_iter_t *it) {
|
||||
IterData *ctx = ecs_get_ctx(it->world);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
if (ctx->component) {
|
||||
ecs_add_id(it->world, it->entities[i], ctx->component);
|
||||
}
|
||||
|
||||
if (ctx->component_2) {
|
||||
ecs_add_id(it->world, it->entities[i], ctx->component_2);
|
||||
}
|
||||
|
||||
ctx->entity_count ++;
|
||||
}
|
||||
}
|
||||
|
||||
void MultiTaskThreadStaging_2_threads_add_to_current(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
ECS_COMPONENT(world, Rotation);
|
||||
ECS_PREFAB(world, Type, Position, Velocity);
|
||||
|
||||
ECS_SYSTEM(world, MultiTaskThread_Add_to_current, EcsOnUpdate, Position);
|
||||
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = MultiTaskThread_Add_to_current,
|
||||
.multi_threaded = true
|
||||
});
|
||||
|
||||
IterData ctx = {.component = ecs_id(Rotation)};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_entity_t ids_1[100];
|
||||
const ecs_entity_t *temp_ids_1 = ecs_bulk_new(world, Position, 100);
|
||||
memcpy(ids_1, temp_ids_1, sizeof(ecs_entity_t) * 100);
|
||||
|
||||
const ecs_entity_t *ids_2 = bulk_new_w_type(world, Type, 100);
|
||||
|
||||
ecs_set_task_threads(world, 2);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_1[i], Position));
|
||||
test_assert( ecs_has(world, ids_1[i], Rotation));
|
||||
test_assert( !ecs_has(world, ids_1[i], Velocity));
|
||||
}
|
||||
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_2[i], Position));
|
||||
test_assert( ecs_has(world, ids_2[i], Rotation));
|
||||
test_assert( ecs_has(world, ids_2[i], Velocity));
|
||||
}
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiTaskThreadStaging_3_threads_add_to_current(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
ECS_COMPONENT(world, Rotation);
|
||||
ECS_PREFAB(world, Type, Position, Velocity);
|
||||
|
||||
ECS_SYSTEM(world, MultiTaskThread_Add_to_current, EcsOnUpdate, Position);
|
||||
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = MultiTaskThread_Add_to_current,
|
||||
.multi_threaded = true
|
||||
});
|
||||
|
||||
IterData ctx = {.component = ecs_id(Rotation)};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_entity_t ids_1[100];
|
||||
const ecs_entity_t *temp_ids_1 = ecs_bulk_new(world, Position, 100);
|
||||
memcpy(ids_1, temp_ids_1, sizeof(ecs_entity_t) * 100);
|
||||
|
||||
const ecs_entity_t *ids_2 = bulk_new_w_type(world, Type, 100);
|
||||
|
||||
ecs_set_task_threads(world, 3);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_1[i], Position));
|
||||
test_assert( ecs_has(world, ids_1[i], Rotation));
|
||||
test_assert( !ecs_has(world, ids_1[i], Velocity));
|
||||
}
|
||||
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_2[i], Position));
|
||||
test_assert( ecs_has(world, ids_2[i], Rotation));
|
||||
test_assert( ecs_has(world, ids_2[i], Velocity));
|
||||
}
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiTaskThreadStaging_4_threads_add_to_current(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
ECS_COMPONENT(world, Rotation);
|
||||
ECS_PREFAB(world, Type, Position, Velocity);
|
||||
|
||||
ECS_SYSTEM(world, MultiTaskThread_Add_to_current, EcsOnUpdate, Position);
|
||||
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = MultiTaskThread_Add_to_current,
|
||||
.multi_threaded = true
|
||||
});
|
||||
|
||||
IterData ctx = {.component = ecs_id(Rotation)};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_entity_t ids_1[100];
|
||||
const ecs_entity_t *temp_ids_1 = ecs_bulk_new(world, Position, 100);
|
||||
memcpy(ids_1, temp_ids_1, sizeof(ecs_entity_t) * 100);
|
||||
|
||||
const ecs_entity_t *ids_2 = bulk_new_w_type(world, Type, 100);
|
||||
|
||||
ecs_set_task_threads(world, 4);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_1[i], Position));
|
||||
test_assert( ecs_has(world, ids_1[i], Rotation));
|
||||
test_assert( !ecs_has(world, ids_1[i], Velocity));
|
||||
}
|
||||
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_2[i], Position));
|
||||
test_assert( ecs_has(world, ids_2[i], Rotation));
|
||||
test_assert( ecs_has(world, ids_2[i], Velocity));
|
||||
}
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiTaskThreadStaging_5_threads_add_to_current(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
ECS_COMPONENT(world, Rotation);
|
||||
ECS_PREFAB(world, Type, Position, Velocity);
|
||||
|
||||
ECS_SYSTEM(world, MultiTaskThread_Add_to_current, EcsOnUpdate, Position);
|
||||
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = MultiTaskThread_Add_to_current,
|
||||
.multi_threaded = true
|
||||
});
|
||||
|
||||
IterData ctx = {.component = ecs_id(Rotation)};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_entity_t ids_1[100];
|
||||
const ecs_entity_t *temp_ids_1 = ecs_bulk_new(world, Position, 100);
|
||||
memcpy(ids_1, temp_ids_1, sizeof(ecs_entity_t) * 100);
|
||||
|
||||
const ecs_entity_t *ids_2 = bulk_new_w_type(world, Type, 100);
|
||||
|
||||
ecs_set_task_threads(world, 5);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_1[i], Position));
|
||||
test_assert( ecs_has(world, ids_1[i], Rotation));
|
||||
test_assert( !ecs_has(world, ids_1[i], Velocity));
|
||||
}
|
||||
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_2[i], Position));
|
||||
test_assert( ecs_has(world, ids_2[i], Rotation));
|
||||
test_assert( ecs_has(world, ids_2[i], Velocity));
|
||||
}
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiTaskThreadStaging_6_threads_add_to_current(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
ECS_COMPONENT(world, Rotation);
|
||||
ECS_PREFAB(world, Type, Position, Velocity);
|
||||
|
||||
ECS_SYSTEM(world, MultiTaskThread_Add_to_current, EcsOnUpdate, Position);
|
||||
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = MultiTaskThread_Add_to_current,
|
||||
.multi_threaded = true
|
||||
});
|
||||
|
||||
IterData ctx = {.component = ecs_id(Rotation)};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_entity_t ids_1[100];
|
||||
const ecs_entity_t *temp_ids_1 = ecs_bulk_new(world, Position, 100);
|
||||
memcpy(ids_1, temp_ids_1, sizeof(ecs_entity_t) * 100);
|
||||
|
||||
const ecs_entity_t *ids_2 = bulk_new_w_type(world, Type, 100);
|
||||
|
||||
ecs_set_task_threads(world, 6);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_1[i], Position));
|
||||
test_assert( ecs_has(world, ids_1[i], Rotation));
|
||||
test_assert( !ecs_has(world, ids_1[i], Velocity));
|
||||
}
|
||||
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_2[i], Position));
|
||||
test_assert( ecs_has(world, ids_2[i], Rotation));
|
||||
test_assert( ecs_has(world, ids_2[i], Velocity));
|
||||
}
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static
|
||||
void InitVelocity(ecs_iter_t *it) {
|
||||
Velocity *v = ecs_field(it, Velocity, 1);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
v[i].x = 10;
|
||||
v[i].y = 20;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void AddVelocity(ecs_iter_t *it) {
|
||||
ecs_id_t ecs_id(Velocity) = ecs_field_id(it, 2);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
ecs_add(it->world, it->entities[i], Velocity);
|
||||
}
|
||||
}
|
||||
|
||||
void MultiTaskThreadStaging_2_threads_on_add(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ECS_OBSERVER(world, InitVelocity, EcsOnAdd, Velocity);
|
||||
ECS_SYSTEM(world, AddVelocity, EcsOnUpdate, Position, Velocity());
|
||||
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = AddVelocity,
|
||||
.multi_threaded = true
|
||||
});
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
const ecs_entity_t *ids = ecs_bulk_new(world, Position, 10);
|
||||
test_assert(ids != NULL);
|
||||
|
||||
ecs_set_task_threads(world, 2);
|
||||
|
||||
ecs_progress(world, 0);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 10; i ++) {
|
||||
ecs_entity_t e = ids[i];
|
||||
test_assert( ecs_has(world, e, Velocity));
|
||||
const Velocity *v = ecs_get(world, e, Velocity);
|
||||
test_assert(v != NULL);
|
||||
test_int(v->x, 10);
|
||||
test_int(v->y, 20);
|
||||
}
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static
|
||||
void New_w_count(ecs_iter_t *it) {
|
||||
ecs_id_t ecs_id(Position) = ecs_field_id(it, 1);
|
||||
|
||||
ecs_bulk_new(it->world, Position, 10);
|
||||
}
|
||||
|
||||
void MultiTaskThreadStaging_new_w_count(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_SYSTEM(world, New_w_count, EcsOnUpdate, Position());
|
||||
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = New_w_count,
|
||||
.multi_threaded = true
|
||||
});
|
||||
|
||||
ecs_set_task_threads(world, 2);
|
||||
|
||||
ecs_progress(world, 0);
|
||||
|
||||
test_int( ecs_count(world, Position), 10);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiTaskThreadStaging_custom_thread_auto_merge(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_entity_t e1 = ecs_new_id(world);
|
||||
ecs_entity_t e2 = ecs_new_id(world);
|
||||
|
||||
ecs_set_stage_count(world, 2);
|
||||
|
||||
ecs_world_t *ctx_1 = ecs_get_stage(world, 0);
|
||||
ecs_world_t *ctx_2 = ecs_get_stage(world, 1);
|
||||
|
||||
ecs_frame_begin(world, 0);
|
||||
ecs_readonly_begin(world);
|
||||
|
||||
/* thread 1 */
|
||||
ecs_defer_begin(ctx_1);
|
||||
ecs_set(ctx_1, e1, Position, {10, 20});
|
||||
test_assert(!ecs_has(world, e1, Position));
|
||||
test_assert(!ecs_has(ctx_1, e1, Position));
|
||||
ecs_defer_end(ctx_1);
|
||||
test_assert(!ecs_has(world, e1, Position));
|
||||
test_assert(!ecs_has(ctx_1, e1, Position));
|
||||
|
||||
/* thread 2 */
|
||||
ecs_defer_begin(ctx_2);
|
||||
ecs_set(ctx_2, e2, Position, {20, 30});
|
||||
test_assert(!ecs_has(world, e2, Position));
|
||||
test_assert(!ecs_has(ctx_2, e2, Position));
|
||||
ecs_defer_end(ctx_2);
|
||||
test_assert(!ecs_has(world, e2, Position));
|
||||
test_assert(!ecs_has(ctx_2, e2, Position));
|
||||
|
||||
ecs_readonly_end(world);
|
||||
ecs_frame_end(world);
|
||||
|
||||
test_assert(ecs_has(world, e1, Position));
|
||||
test_assert(ecs_has(world, e2, Position));
|
||||
|
||||
const Position *p1 = ecs_get(world, e1, Position);
|
||||
test_int(p1->x, 10);
|
||||
test_int(p1->y, 20);
|
||||
|
||||
const Position *p2 = ecs_get(world, e2, Position);
|
||||
test_int(p2->x, 20);
|
||||
test_int(p2->y, 30);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiTaskThreadStaging_custom_thread_manual_merge(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_entity_t e1 = ecs_new_id(world);
|
||||
ecs_entity_t e2 = ecs_new_id(world);
|
||||
|
||||
ecs_set_automerge(world, false);
|
||||
|
||||
ecs_set_stage_count(world, 2);
|
||||
|
||||
ecs_world_t *ctx_1 = ecs_get_stage(world, 0);
|
||||
ecs_world_t *ctx_2 = ecs_get_stage(world, 1);
|
||||
|
||||
ecs_frame_begin(world, 0);
|
||||
ecs_readonly_begin(world);
|
||||
|
||||
/* thread 1 */
|
||||
ecs_defer_begin(ctx_1);
|
||||
ecs_set(ctx_1, e1, Position, {10, 20});
|
||||
test_assert(!ecs_has(world, e1, Position));
|
||||
test_assert(!ecs_has(ctx_1, e1, Position));
|
||||
ecs_defer_end(ctx_1);
|
||||
test_assert(!ecs_has(world, e1, Position));
|
||||
test_assert(!ecs_has(ctx_1, e1, Position));
|
||||
|
||||
/* thread 2 */
|
||||
ecs_defer_begin(ctx_2);
|
||||
ecs_set(ctx_2, e2, Position, {20, 30});
|
||||
test_assert(!ecs_has(world, e2, Position));
|
||||
test_assert(!ecs_has(ctx_2, e2, Position));
|
||||
ecs_defer_end(ctx_2);
|
||||
test_assert(!ecs_has(world, e2, Position));
|
||||
test_assert(!ecs_has(ctx_2, e2, Position));
|
||||
|
||||
ecs_readonly_end(world);
|
||||
ecs_frame_end(world);
|
||||
|
||||
test_assert(!ecs_has(world, e1, Position));
|
||||
test_assert(!ecs_has(world, e2, Position));
|
||||
|
||||
ecs_merge(world);
|
||||
|
||||
test_assert(ecs_has(world, e1, Position));
|
||||
test_assert(ecs_has(world, e2, Position));
|
||||
|
||||
const Position *p1 = ecs_get(world, e1, Position);
|
||||
test_int(p1->x, 10);
|
||||
test_int(p1->y, 20);
|
||||
|
||||
const Position *p2 = ecs_get(world, e2, Position);
|
||||
test_int(p2->x, 20);
|
||||
test_int(p2->y, 30);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiTaskThreadStaging_custom_thread_partial_manual_merge(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_entity_t e1 = ecs_new_id(world);
|
||||
ecs_entity_t e2 = ecs_new_id(world);
|
||||
|
||||
ecs_set_stage_count(world, 2);
|
||||
|
||||
ecs_world_t *ctx_1 = ecs_get_stage(world, 0);
|
||||
ecs_world_t *ctx_2 = ecs_get_stage(world, 1);
|
||||
|
||||
/* Only disable automerging for ctx_2 */
|
||||
ecs_set_automerge(ctx_2, false);
|
||||
|
||||
ecs_frame_begin(world, 0);
|
||||
ecs_readonly_begin(world);
|
||||
|
||||
/* thread 1 */
|
||||
ecs_defer_begin(ctx_1);
|
||||
ecs_set(ctx_1, e1, Position, {10, 20});
|
||||
test_assert(!ecs_has(world, e1, Position));
|
||||
test_assert(!ecs_has(ctx_1, e1, Position));
|
||||
ecs_defer_end(ctx_1);
|
||||
test_assert(!ecs_has(world, e1, Position));
|
||||
test_assert(!ecs_has(ctx_1, e1, Position));
|
||||
|
||||
/* thread 2 */
|
||||
ecs_defer_begin(ctx_2);
|
||||
ecs_set(ctx_2, e2, Position, {20, 30});
|
||||
test_assert(!ecs_has(world, e2, Position));
|
||||
test_assert(!ecs_has(ctx_2, e2, Position));
|
||||
ecs_defer_end(ctx_2);
|
||||
test_assert(!ecs_has(world, e2, Position));
|
||||
test_assert(!ecs_has(ctx_2, e2, Position));
|
||||
|
||||
ecs_readonly_end(world);
|
||||
ecs_frame_end(world);
|
||||
|
||||
test_assert(ecs_has(world, e1, Position));
|
||||
test_assert(!ecs_has(world, e2, Position));
|
||||
|
||||
const Position *p1 = ecs_get(world, e1, Position);
|
||||
test_int(p1->x, 10);
|
||||
test_int(p1->y, 20);
|
||||
|
||||
ecs_merge(ctx_2);
|
||||
|
||||
test_assert(ecs_has(world, e1, Position));
|
||||
test_assert(ecs_has(world, e2, Position));
|
||||
|
||||
p1 = ecs_get(world, e1, Position);
|
||||
test_int(p1->x, 10);
|
||||
test_int(p1->y, 20);
|
||||
|
||||
const Position *p2 = ecs_get(world, e2, Position);
|
||||
test_int(p2->x, 20);
|
||||
test_int(p2->y, 30);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiTaskThreadStaging_set_pair_w_new_target_readonly(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_set_task_threads(world, 2);
|
||||
|
||||
ecs_entity_t e = ecs_new_id(world);
|
||||
|
||||
ecs_world_t *thr_1 = ecs_get_stage(world, 0);
|
||||
|
||||
ecs_frame_begin(world, 0);
|
||||
ecs_readonly_begin(world);
|
||||
|
||||
ecs_entity_t tgt = ecs_new_id(thr_1);
|
||||
ecs_set_pair(thr_1, e, Position, tgt, {10, 20});
|
||||
|
||||
ecs_readonly_end(world);
|
||||
ecs_frame_end(world);
|
||||
|
||||
test_assert(ecs_has_pair(world, e, ecs_id(Position), tgt));
|
||||
|
||||
const Position *p = ecs_get_pair(world, e, Position, tgt);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiTaskThreadStaging_set_pair_w_new_target_tgt_component_readonly(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_set_task_threads(world, 2);
|
||||
|
||||
ecs_entity_t e = ecs_new_id(world);
|
||||
|
||||
ecs_world_t *thr_1 = ecs_get_stage(world, 0);
|
||||
|
||||
ecs_frame_begin(world, 0);
|
||||
ecs_readonly_begin(world);
|
||||
|
||||
ecs_entity_t tgt = ecs_new_id(thr_1);
|
||||
ecs_set_pair_second(thr_1, e, tgt, Position, {10, 20});
|
||||
|
||||
ecs_readonly_end(world);
|
||||
ecs_frame_end(world);
|
||||
|
||||
test_assert(ecs_has_pair(world, e, tgt, ecs_id(Position)));
|
||||
|
||||
const Position *p = ecs_get_pair_second(world, e, tgt, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiTaskThreadStaging_set_pair_w_new_target_defer(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_set_task_threads(world, 2);
|
||||
|
||||
ecs_entity_t e = ecs_new_id(world);
|
||||
|
||||
ecs_defer_begin(world);
|
||||
|
||||
ecs_entity_t tgt = ecs_new_id(world);
|
||||
ecs_set_pair(world, e, Position, tgt, {10, 20});
|
||||
|
||||
ecs_defer_end(world);
|
||||
|
||||
test_assert(ecs_has_pair(world, e, ecs_id(Position), tgt));
|
||||
|
||||
const Position *p = ecs_get_pair(world, e, Position, tgt);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiTaskThreadStaging_set_pair_w_new_target_tgt_component_defer(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_set_task_threads(world, 2);
|
||||
|
||||
ecs_entity_t e = ecs_new_id(world);
|
||||
|
||||
ecs_defer_begin(world);
|
||||
|
||||
ecs_entity_t tgt = ecs_new_id(world);
|
||||
ecs_set_pair_second(world, e, tgt, Position, {10, 20});
|
||||
|
||||
ecs_defer_end(world);
|
||||
|
||||
test_assert(ecs_has_pair(world, e, tgt, ecs_id(Position)));
|
||||
|
||||
const Position *p = ecs_get_pair_second(world, e, tgt, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
1384
engine/libs/flecs/test/addons/src/MultiThread.c
Normal file
1384
engine/libs/flecs/test/addons/src/MultiThread.c
Normal file
File diff suppressed because it is too large
Load Diff
613
engine/libs/flecs/test/addons/src/MultiThreadStaging.c
Normal file
613
engine/libs/flecs/test/addons/src/MultiThreadStaging.c
Normal file
@@ -0,0 +1,613 @@
|
||||
#include <addons.h>
|
||||
|
||||
void MultiThreadStaging_setup(void) {
|
||||
ecs_log_set_level(-3);
|
||||
}
|
||||
|
||||
static
|
||||
void Add_to_current(ecs_iter_t *it) {
|
||||
IterData *ctx = ecs_get_ctx(it->world);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
if (ctx->component) {
|
||||
ecs_add_id(it->world, it->entities[i], ctx->component);
|
||||
}
|
||||
|
||||
if (ctx->component_2) {
|
||||
ecs_add_id(it->world, it->entities[i], ctx->component_2);
|
||||
}
|
||||
|
||||
ctx->entity_count ++;
|
||||
}
|
||||
}
|
||||
|
||||
void MultiThreadStaging_2_threads_add_to_current(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
ECS_COMPONENT(world, Rotation);
|
||||
ECS_PREFAB(world, Type, Position, Velocity);
|
||||
|
||||
ECS_SYSTEM(world, Add_to_current, EcsOnUpdate, Position);
|
||||
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = Add_to_current,
|
||||
.multi_threaded = true
|
||||
});
|
||||
|
||||
IterData ctx = {.component = ecs_id(Rotation)};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_entity_t ids_1[100];
|
||||
const ecs_entity_t *temp_ids_1 = ecs_bulk_new(world, Position, 100);
|
||||
memcpy(ids_1, temp_ids_1, sizeof(ecs_entity_t) * 100);
|
||||
|
||||
const ecs_entity_t *ids_2 = bulk_new_w_type(world, Type, 100);
|
||||
|
||||
ecs_set_threads(world, 2);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_1[i], Position));
|
||||
test_assert( ecs_has(world, ids_1[i], Rotation));
|
||||
test_assert( !ecs_has(world, ids_1[i], Velocity));
|
||||
}
|
||||
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_2[i], Position));
|
||||
test_assert( ecs_has(world, ids_2[i], Rotation));
|
||||
test_assert( ecs_has(world, ids_2[i], Velocity));
|
||||
}
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiThreadStaging_3_threads_add_to_current(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
ECS_COMPONENT(world, Rotation);
|
||||
ECS_PREFAB(world, Type, Position, Velocity);
|
||||
|
||||
ECS_SYSTEM(world, Add_to_current, EcsOnUpdate, Position);
|
||||
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = Add_to_current,
|
||||
.multi_threaded = true
|
||||
});
|
||||
|
||||
IterData ctx = {.component = ecs_id(Rotation)};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_entity_t ids_1[100];
|
||||
const ecs_entity_t *temp_ids_1 = ecs_bulk_new(world, Position, 100);
|
||||
memcpy(ids_1, temp_ids_1, sizeof(ecs_entity_t) * 100);
|
||||
|
||||
const ecs_entity_t *ids_2 = bulk_new_w_type(world, Type, 100);
|
||||
|
||||
ecs_set_threads(world, 3);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_1[i], Position));
|
||||
test_assert( ecs_has(world, ids_1[i], Rotation));
|
||||
test_assert( !ecs_has(world, ids_1[i], Velocity));
|
||||
}
|
||||
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_2[i], Position));
|
||||
test_assert( ecs_has(world, ids_2[i], Rotation));
|
||||
test_assert( ecs_has(world, ids_2[i], Velocity));
|
||||
}
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiThreadStaging_4_threads_add_to_current(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
ECS_COMPONENT(world, Rotation);
|
||||
ECS_PREFAB(world, Type, Position, Velocity);
|
||||
|
||||
ECS_SYSTEM(world, Add_to_current, EcsOnUpdate, Position);
|
||||
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = Add_to_current,
|
||||
.multi_threaded = true
|
||||
});
|
||||
|
||||
IterData ctx = {.component = ecs_id(Rotation)};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_entity_t ids_1[100];
|
||||
const ecs_entity_t *temp_ids_1 = ecs_bulk_new(world, Position, 100);
|
||||
memcpy(ids_1, temp_ids_1, sizeof(ecs_entity_t) * 100);
|
||||
|
||||
const ecs_entity_t *ids_2 = bulk_new_w_type(world, Type, 100);
|
||||
|
||||
ecs_set_threads(world, 4);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_1[i], Position));
|
||||
test_assert( ecs_has(world, ids_1[i], Rotation));
|
||||
test_assert( !ecs_has(world, ids_1[i], Velocity));
|
||||
}
|
||||
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_2[i], Position));
|
||||
test_assert( ecs_has(world, ids_2[i], Rotation));
|
||||
test_assert( ecs_has(world, ids_2[i], Velocity));
|
||||
}
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiThreadStaging_5_threads_add_to_current(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
ECS_COMPONENT(world, Rotation);
|
||||
ECS_PREFAB(world, Type, Position, Velocity);
|
||||
|
||||
ECS_SYSTEM(world, Add_to_current, EcsOnUpdate, Position);
|
||||
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = Add_to_current,
|
||||
.multi_threaded = true
|
||||
});
|
||||
|
||||
IterData ctx = {.component = ecs_id(Rotation)};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_entity_t ids_1[100];
|
||||
const ecs_entity_t *temp_ids_1 = ecs_bulk_new(world, Position, 100);
|
||||
memcpy(ids_1, temp_ids_1, sizeof(ecs_entity_t) * 100);
|
||||
|
||||
const ecs_entity_t *ids_2 = bulk_new_w_type(world, Type, 100);
|
||||
|
||||
ecs_set_threads(world, 5);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_1[i], Position));
|
||||
test_assert( ecs_has(world, ids_1[i], Rotation));
|
||||
test_assert( !ecs_has(world, ids_1[i], Velocity));
|
||||
}
|
||||
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_2[i], Position));
|
||||
test_assert( ecs_has(world, ids_2[i], Rotation));
|
||||
test_assert( ecs_has(world, ids_2[i], Velocity));
|
||||
}
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiThreadStaging_6_threads_add_to_current(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
ECS_COMPONENT(world, Rotation);
|
||||
ECS_PREFAB(world, Type, Position, Velocity);
|
||||
|
||||
ECS_SYSTEM(world, Add_to_current, EcsOnUpdate, Position);
|
||||
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = Add_to_current,
|
||||
.multi_threaded = true
|
||||
});
|
||||
|
||||
IterData ctx = {.component = ecs_id(Rotation)};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_entity_t ids_1[100];
|
||||
const ecs_entity_t *temp_ids_1 = ecs_bulk_new(world, Position, 100);
|
||||
memcpy(ids_1, temp_ids_1, sizeof(ecs_entity_t) * 100);
|
||||
|
||||
const ecs_entity_t *ids_2 = bulk_new_w_type(world, Type, 100);
|
||||
|
||||
ecs_set_threads(world, 6);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_1[i], Position));
|
||||
test_assert( ecs_has(world, ids_1[i], Rotation));
|
||||
test_assert( !ecs_has(world, ids_1[i], Velocity));
|
||||
}
|
||||
|
||||
for (i = 0; i < 100; i ++) {
|
||||
test_assert( ecs_has(world, ids_2[i], Position));
|
||||
test_assert( ecs_has(world, ids_2[i], Rotation));
|
||||
test_assert( ecs_has(world, ids_2[i], Velocity));
|
||||
}
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static
|
||||
void InitVelocity(ecs_iter_t *it) {
|
||||
Velocity *v = ecs_field(it, Velocity, 1);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
v[i].x = 10;
|
||||
v[i].y = 20;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void AddVelocity(ecs_iter_t *it) {
|
||||
ecs_id_t ecs_id(Velocity) = ecs_field_id(it, 2);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
ecs_add(it->world, it->entities[i], Velocity);
|
||||
}
|
||||
}
|
||||
|
||||
void MultiThreadStaging_2_threads_on_add(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ECS_OBSERVER(world, InitVelocity, EcsOnAdd, Velocity);
|
||||
ECS_SYSTEM(world, AddVelocity, EcsOnUpdate, Position, Velocity());
|
||||
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = AddVelocity,
|
||||
.multi_threaded = true
|
||||
});
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
const ecs_entity_t *ids = ecs_bulk_new(world, Position, 10);
|
||||
test_assert(ids != NULL);
|
||||
|
||||
ecs_set_threads(world, 2);
|
||||
|
||||
ecs_progress(world, 0);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 10; i ++) {
|
||||
ecs_entity_t e = ids[i];
|
||||
test_assert( ecs_has(world, e, Velocity));
|
||||
const Velocity *v = ecs_get(world, e, Velocity);
|
||||
test_assert(v != NULL);
|
||||
test_int(v->x, 10);
|
||||
test_int(v->y, 20);
|
||||
}
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static
|
||||
void New_w_count(ecs_iter_t *it) {
|
||||
ecs_id_t ecs_id(Position) = ecs_field_id(it, 1);
|
||||
|
||||
ecs_bulk_new(it->world, Position, 10);
|
||||
}
|
||||
|
||||
void MultiThreadStaging_new_w_count(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_SYSTEM(world, New_w_count, EcsOnUpdate, Position());
|
||||
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = New_w_count,
|
||||
.multi_threaded = true
|
||||
});
|
||||
|
||||
ecs_set_threads(world, 2);
|
||||
|
||||
ecs_progress(world, 0);
|
||||
|
||||
test_int( ecs_count(world, Position), 10);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiThreadStaging_custom_thread_auto_merge(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_entity_t e1 = ecs_new_id(world);
|
||||
ecs_entity_t e2 = ecs_new_id(world);
|
||||
|
||||
ecs_set_stage_count(world, 2);
|
||||
|
||||
ecs_world_t *ctx_1 = ecs_get_stage(world, 0);
|
||||
ecs_world_t *ctx_2 = ecs_get_stage(world, 1);
|
||||
|
||||
ecs_frame_begin(world, 0);
|
||||
ecs_readonly_begin(world);
|
||||
|
||||
/* thread 1 */
|
||||
ecs_defer_begin(ctx_1);
|
||||
ecs_set(ctx_1, e1, Position, {10, 20});
|
||||
test_assert(!ecs_has(world, e1, Position));
|
||||
test_assert(!ecs_has(ctx_1, e1, Position));
|
||||
ecs_defer_end(ctx_1);
|
||||
test_assert(!ecs_has(world, e1, Position));
|
||||
test_assert(!ecs_has(ctx_1, e1, Position));
|
||||
|
||||
/* thread 2 */
|
||||
ecs_defer_begin(ctx_2);
|
||||
ecs_set(ctx_2, e2, Position, {20, 30});
|
||||
test_assert(!ecs_has(world, e2, Position));
|
||||
test_assert(!ecs_has(ctx_2, e2, Position));
|
||||
ecs_defer_end(ctx_2);
|
||||
test_assert(!ecs_has(world, e2, Position));
|
||||
test_assert(!ecs_has(ctx_2, e2, Position));
|
||||
|
||||
ecs_readonly_end(world);
|
||||
ecs_frame_end(world);
|
||||
|
||||
test_assert(ecs_has(world, e1, Position));
|
||||
test_assert(ecs_has(world, e2, Position));
|
||||
|
||||
const Position *p1 = ecs_get(world, e1, Position);
|
||||
test_int(p1->x, 10);
|
||||
test_int(p1->y, 20);
|
||||
|
||||
const Position *p2 = ecs_get(world, e2, Position);
|
||||
test_int(p2->x, 20);
|
||||
test_int(p2->y, 30);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiThreadStaging_custom_thread_manual_merge(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_entity_t e1 = ecs_new_id(world);
|
||||
ecs_entity_t e2 = ecs_new_id(world);
|
||||
|
||||
ecs_set_automerge(world, false);
|
||||
|
||||
ecs_set_stage_count(world, 2);
|
||||
|
||||
ecs_world_t *ctx_1 = ecs_get_stage(world, 0);
|
||||
ecs_world_t *ctx_2 = ecs_get_stage(world, 1);
|
||||
|
||||
ecs_frame_begin(world, 0);
|
||||
ecs_readonly_begin(world);
|
||||
|
||||
/* thread 1 */
|
||||
ecs_defer_begin(ctx_1);
|
||||
ecs_set(ctx_1, e1, Position, {10, 20});
|
||||
test_assert(!ecs_has(world, e1, Position));
|
||||
test_assert(!ecs_has(ctx_1, e1, Position));
|
||||
ecs_defer_end(ctx_1);
|
||||
test_assert(!ecs_has(world, e1, Position));
|
||||
test_assert(!ecs_has(ctx_1, e1, Position));
|
||||
|
||||
/* thread 2 */
|
||||
ecs_defer_begin(ctx_2);
|
||||
ecs_set(ctx_2, e2, Position, {20, 30});
|
||||
test_assert(!ecs_has(world, e2, Position));
|
||||
test_assert(!ecs_has(ctx_2, e2, Position));
|
||||
ecs_defer_end(ctx_2);
|
||||
test_assert(!ecs_has(world, e2, Position));
|
||||
test_assert(!ecs_has(ctx_2, e2, Position));
|
||||
|
||||
ecs_readonly_end(world);
|
||||
ecs_frame_end(world);
|
||||
|
||||
test_assert(!ecs_has(world, e1, Position));
|
||||
test_assert(!ecs_has(world, e2, Position));
|
||||
|
||||
ecs_merge(world);
|
||||
|
||||
test_assert(ecs_has(world, e1, Position));
|
||||
test_assert(ecs_has(world, e2, Position));
|
||||
|
||||
const Position *p1 = ecs_get(world, e1, Position);
|
||||
test_int(p1->x, 10);
|
||||
test_int(p1->y, 20);
|
||||
|
||||
const Position *p2 = ecs_get(world, e2, Position);
|
||||
test_int(p2->x, 20);
|
||||
test_int(p2->y, 30);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiThreadStaging_custom_thread_partial_manual_merge(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_entity_t e1 = ecs_new_id(world);
|
||||
ecs_entity_t e2 = ecs_new_id(world);
|
||||
|
||||
ecs_set_stage_count(world, 2);
|
||||
|
||||
ecs_world_t *ctx_1 = ecs_get_stage(world, 0);
|
||||
ecs_world_t *ctx_2 = ecs_get_stage(world, 1);
|
||||
|
||||
/* Only disable automerging for ctx_2 */
|
||||
ecs_set_automerge(ctx_2, false);
|
||||
|
||||
ecs_frame_begin(world, 0);
|
||||
ecs_readonly_begin(world);
|
||||
|
||||
/* thread 1 */
|
||||
ecs_defer_begin(ctx_1);
|
||||
ecs_set(ctx_1, e1, Position, {10, 20});
|
||||
test_assert(!ecs_has(world, e1, Position));
|
||||
test_assert(!ecs_has(ctx_1, e1, Position));
|
||||
ecs_defer_end(ctx_1);
|
||||
test_assert(!ecs_has(world, e1, Position));
|
||||
test_assert(!ecs_has(ctx_1, e1, Position));
|
||||
|
||||
/* thread 2 */
|
||||
ecs_defer_begin(ctx_2);
|
||||
ecs_set(ctx_2, e2, Position, {20, 30});
|
||||
test_assert(!ecs_has(world, e2, Position));
|
||||
test_assert(!ecs_has(ctx_2, e2, Position));
|
||||
ecs_defer_end(ctx_2);
|
||||
test_assert(!ecs_has(world, e2, Position));
|
||||
test_assert(!ecs_has(ctx_2, e2, Position));
|
||||
|
||||
ecs_readonly_end(world);
|
||||
ecs_frame_end(world);
|
||||
|
||||
test_assert(ecs_has(world, e1, Position));
|
||||
test_assert(!ecs_has(world, e2, Position));
|
||||
|
||||
const Position *p1 = ecs_get(world, e1, Position);
|
||||
test_int(p1->x, 10);
|
||||
test_int(p1->y, 20);
|
||||
|
||||
ecs_merge(ctx_2);
|
||||
|
||||
test_assert(ecs_has(world, e1, Position));
|
||||
test_assert(ecs_has(world, e2, Position));
|
||||
|
||||
p1 = ecs_get(world, e1, Position);
|
||||
test_int(p1->x, 10);
|
||||
test_int(p1->y, 20);
|
||||
|
||||
const Position *p2 = ecs_get(world, e2, Position);
|
||||
test_int(p2->x, 20);
|
||||
test_int(p2->y, 30);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiThreadStaging_set_pair_w_new_target_readonly(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_set_threads(world, 2);
|
||||
|
||||
ecs_entity_t e = ecs_new_id(world);
|
||||
|
||||
ecs_world_t *thr_1 = ecs_get_stage(world, 0);
|
||||
|
||||
ecs_frame_begin(world, 0);
|
||||
ecs_readonly_begin(world);
|
||||
|
||||
ecs_entity_t tgt = ecs_new_id(thr_1);
|
||||
ecs_set_pair(thr_1, e, Position, tgt, {10, 20});
|
||||
|
||||
ecs_readonly_end(world);
|
||||
ecs_frame_end(world);
|
||||
|
||||
test_assert(ecs_has_pair(world, e, ecs_id(Position), tgt));
|
||||
|
||||
const Position *p = ecs_get_pair(world, e, Position, tgt);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiThreadStaging_set_pair_w_new_target_tgt_component_readonly(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_set_threads(world, 2);
|
||||
|
||||
ecs_entity_t e = ecs_new_id(world);
|
||||
|
||||
ecs_world_t *thr_1 = ecs_get_stage(world, 0);
|
||||
|
||||
ecs_frame_begin(world, 0);
|
||||
ecs_readonly_begin(world);
|
||||
|
||||
ecs_entity_t tgt = ecs_new_id(thr_1);
|
||||
ecs_set_pair_second(thr_1, e, tgt, Position, {10, 20});
|
||||
|
||||
ecs_readonly_end(world);
|
||||
ecs_frame_end(world);
|
||||
|
||||
test_assert(ecs_has_pair(world, e, tgt, ecs_id(Position)));
|
||||
|
||||
const Position *p = ecs_get_pair_second(world, e, tgt, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiThreadStaging_set_pair_w_new_target_defer(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_set_threads(world, 2);
|
||||
|
||||
ecs_entity_t e = ecs_new_id(world);
|
||||
|
||||
ecs_defer_begin(world);
|
||||
|
||||
ecs_entity_t tgt = ecs_new_id(world);
|
||||
ecs_set_pair(world, e, Position, tgt, {10, 20});
|
||||
|
||||
ecs_defer_end(world);
|
||||
|
||||
test_assert(ecs_has_pair(world, e, ecs_id(Position), tgt));
|
||||
|
||||
const Position *p = ecs_get_pair(world, e, Position, tgt);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void MultiThreadStaging_set_pair_w_new_target_tgt_component_defer(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_set_threads(world, 2);
|
||||
|
||||
ecs_entity_t e = ecs_new_id(world);
|
||||
|
||||
ecs_defer_begin(world);
|
||||
|
||||
ecs_entity_t tgt = ecs_new_id(world);
|
||||
ecs_set_pair_second(world, e, tgt, Position, {10, 20});
|
||||
|
||||
ecs_defer_end(world);
|
||||
|
||||
test_assert(ecs_has_pair(world, e, tgt, ecs_id(Position)));
|
||||
|
||||
const Position *p = ecs_get_pair_second(world, e, tgt, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
5557
engine/libs/flecs/test/addons/src/Parser.c
Normal file
5557
engine/libs/flecs/test/addons/src/Parser.c
Normal file
File diff suppressed because it is too large
Load Diff
3208
engine/libs/flecs/test/addons/src/Pipeline.c
Normal file
3208
engine/libs/flecs/test/addons/src/Pipeline.c
Normal file
File diff suppressed because it is too large
Load Diff
7734
engine/libs/flecs/test/addons/src/Plecs.c
Normal file
7734
engine/libs/flecs/test/addons/src/Plecs.c
Normal file
File diff suppressed because it is too large
Load Diff
33
engine/libs/flecs/test/addons/src/Rest.c
Normal file
33
engine/libs/flecs/test/addons/src/Rest.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <addons.h>
|
||||
|
||||
void Rest_teardown(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_singleton_set(world, EcsRest, {27760});
|
||||
|
||||
ecs_fini(world);
|
||||
|
||||
test_assert(true); // Ensure teardown was successful
|
||||
}
|
||||
|
||||
void Rest_get(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_http_server_t *srv = ecs_rest_server_init(world, NULL);
|
||||
test_assert(srv != NULL);
|
||||
|
||||
ecs_http_reply_t reply = ECS_HTTP_REPLY_INIT;
|
||||
test_int(0, ecs_http_server_request(srv, "GET",
|
||||
"/entity/flecs/core/World?label=true", &reply));
|
||||
test_int(reply.code, 200);
|
||||
|
||||
char *reply_str = ecs_strbuf_get(&reply.body);
|
||||
test_assert(reply_str != NULL);
|
||||
test_str(reply_str,
|
||||
"{\"path\":\"flecs.core.World\", \"label\":\"World\", \"ids\":[]}");
|
||||
ecs_os_free(reply_str);
|
||||
|
||||
ecs_rest_server_fini(srv);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
4006
engine/libs/flecs/test/addons/src/RulesBasic.c
Normal file
4006
engine/libs/flecs/test/addons/src/RulesBasic.c
Normal file
File diff suppressed because it is too large
Load Diff
2865
engine/libs/flecs/test/addons/src/RulesBuiltinPredicates.c
Normal file
2865
engine/libs/flecs/test/addons/src/RulesBuiltinPredicates.c
Normal file
File diff suppressed because it is too large
Load Diff
3369
engine/libs/flecs/test/addons/src/RulesComponentInheritance.c
Normal file
3369
engine/libs/flecs/test/addons/src/RulesComponentInheritance.c
Normal file
File diff suppressed because it is too large
Load Diff
6423
engine/libs/flecs/test/addons/src/RulesOperators.c
Normal file
6423
engine/libs/flecs/test/addons/src/RulesOperators.c
Normal file
File diff suppressed because it is too large
Load Diff
208
engine/libs/flecs/test/addons/src/RulesRecycled.c
Normal file
208
engine/libs/flecs/test/addons/src/RulesRecycled.c
Normal file
@@ -0,0 +1,208 @@
|
||||
#include <addons.h>
|
||||
|
||||
static ecs_entity_t recycled_id(ecs_world_t *world, const char *name) {
|
||||
ecs_entity_t result = ecs_new_id(world);
|
||||
ecs_delete(world, result);
|
||||
ecs_entity_t result_2 = ecs_new_id(world);
|
||||
test_assert(result_2 != (uint32_t)result);
|
||||
ecs_set_name(world, result_2, name);
|
||||
return result_2;
|
||||
}
|
||||
|
||||
void RulesRecycled_recycled_vars(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, Tag);
|
||||
|
||||
ecs_entity_t src = recycled_id(world, "src");
|
||||
ecs_entity_t rel = recycled_id(world, "rel");
|
||||
ecs_add(world, src, Tag);
|
||||
ecs_add_id(world, src, rel);
|
||||
|
||||
ecs_rule_t *r = ecs_rule(world, {
|
||||
.expr = "$x($y), Tag($y)"
|
||||
});
|
||||
|
||||
test_assert(r != NULL);
|
||||
|
||||
int32_t x_var = ecs_rule_find_var(r, "x");
|
||||
test_assert(x_var != -1);
|
||||
int32_t y_var = ecs_rule_find_var(r, "y");
|
||||
test_assert(y_var != -1);
|
||||
|
||||
ecs_iter_t it = ecs_rule_iter(world, r);
|
||||
test_bool(true, ecs_rule_next(&it));
|
||||
test_uint(0, it.count);
|
||||
test_uint(Tag, ecs_field_id(&it, 1));
|
||||
test_uint(Tag, ecs_field_id(&it, 2));
|
||||
test_uint(src, ecs_field_src(&it, 1));
|
||||
test_uint(src, ecs_field_src(&it, 2));
|
||||
test_uint(Tag, ecs_iter_get_var(&it, x_var));
|
||||
test_uint(src, ecs_iter_get_var(&it, y_var));
|
||||
|
||||
test_bool(true, ecs_rule_next(&it));
|
||||
test_uint(0, it.count);
|
||||
test_uint(rel, ecs_field_id(&it, 1));
|
||||
test_uint(Tag, ecs_field_id(&it, 2));
|
||||
test_uint(src, ecs_field_src(&it, 1));
|
||||
test_uint(src, ecs_field_src(&it, 2));
|
||||
test_uint(rel, ecs_iter_get_var(&it, x_var));
|
||||
test_uint(src, ecs_iter_get_var(&it, y_var));
|
||||
|
||||
test_bool(false, ecs_rule_next(&it));
|
||||
|
||||
ecs_rule_fini(r);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void RulesRecycled_recycled_pair_vars(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, Tag);
|
||||
|
||||
ecs_entity_t src = recycled_id(world, "src");
|
||||
ecs_entity_t rel = recycled_id(world, "rel");
|
||||
ecs_entity_t tgt = recycled_id(world, "tgt");
|
||||
ecs_add(world, src, Tag);
|
||||
ecs_add_pair(world, src, rel, tgt);
|
||||
|
||||
ecs_rule_t *r = ecs_rule(world, {
|
||||
.expr = "$x($y, $z), Tag($y)"
|
||||
});
|
||||
|
||||
test_assert(r != NULL);
|
||||
|
||||
int32_t x_var = ecs_rule_find_var(r, "x");
|
||||
test_assert(x_var != -1);
|
||||
int32_t y_var = ecs_rule_find_var(r, "y");
|
||||
test_assert(y_var != -1);
|
||||
int32_t z_var = ecs_rule_find_var(r, "z");
|
||||
test_assert(z_var != -1);
|
||||
|
||||
ecs_iter_t it = ecs_rule_iter(world, r);
|
||||
test_bool(true, ecs_rule_next(&it));
|
||||
test_uint(0, it.count);
|
||||
test_uint(ecs_pair(ecs_id(EcsIdentifier), EcsName), ecs_field_id(&it, 1));
|
||||
test_uint(Tag, ecs_field_id(&it, 2));
|
||||
test_uint(src, ecs_field_src(&it, 1));
|
||||
test_uint(src, ecs_field_src(&it, 2));
|
||||
test_uint(ecs_id(EcsIdentifier), ecs_iter_get_var(&it, x_var));
|
||||
test_uint(src, ecs_iter_get_var(&it, y_var));
|
||||
test_uint(EcsName, ecs_iter_get_var(&it, z_var));
|
||||
|
||||
test_bool(true, ecs_rule_next(&it));
|
||||
test_uint(0, it.count);
|
||||
test_uint(ecs_pair(rel, tgt), ecs_field_id(&it, 1));
|
||||
test_uint(Tag, ecs_field_id(&it, 2));
|
||||
test_uint(src, ecs_field_src(&it, 1));
|
||||
test_uint(src, ecs_field_src(&it, 2));
|
||||
test_uint(rel, ecs_iter_get_var(&it, x_var));
|
||||
test_uint(src, ecs_iter_get_var(&it, y_var));
|
||||
test_uint(tgt, ecs_iter_get_var(&it, z_var));
|
||||
|
||||
test_bool(false, ecs_rule_next(&it));
|
||||
|
||||
ecs_rule_fini(r);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void RulesRecycled_recycled_this_ent_var(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, Tag);
|
||||
|
||||
ecs_entity_t src = recycled_id(world, "src");
|
||||
ecs_entity_t rel = recycled_id(world, "rel");
|
||||
ecs_entity_t tgt = recycled_id(world, "tgt");
|
||||
ecs_add(world, src, Tag);
|
||||
ecs_add_pair(world, src, rel, tgt);
|
||||
|
||||
ecs_rule_t *r = ecs_rule(world, {
|
||||
.expr = "$x($y, $this), Tag($y)"
|
||||
});
|
||||
|
||||
test_assert(r != NULL);
|
||||
|
||||
int32_t x_var = ecs_rule_find_var(r, "x");
|
||||
test_assert(x_var != -1);
|
||||
int32_t y_var = ecs_rule_find_var(r, "y");
|
||||
test_assert(y_var != -1);
|
||||
int32_t this_var = ecs_rule_find_var(r, "This");
|
||||
test_assert(this_var != -1);
|
||||
|
||||
ecs_iter_t it = ecs_rule_iter(world, r);
|
||||
test_bool(true, ecs_rule_next(&it));
|
||||
test_uint(1, it.count);
|
||||
test_uint(ecs_pair(ecs_id(EcsIdentifier), EcsName), ecs_field_id(&it, 1));
|
||||
test_uint(Tag, ecs_field_id(&it, 2));
|
||||
test_uint(src, ecs_field_src(&it, 1));
|
||||
test_uint(src, ecs_field_src(&it, 2));
|
||||
test_uint(ecs_id(EcsIdentifier), ecs_iter_get_var(&it, x_var));
|
||||
test_uint(src, ecs_iter_get_var(&it, y_var));
|
||||
test_uint(EcsName, ecs_iter_get_var(&it, this_var));
|
||||
test_uint(EcsName, it.entities[0]);
|
||||
|
||||
test_bool(true, ecs_rule_next(&it));
|
||||
test_uint(1, it.count);
|
||||
test_uint(ecs_pair(rel, tgt), ecs_field_id(&it, 1));
|
||||
test_uint(Tag, ecs_field_id(&it, 2));
|
||||
test_uint(src, ecs_field_src(&it, 1));
|
||||
test_uint(src, ecs_field_src(&it, 2));
|
||||
test_uint(rel, ecs_iter_get_var(&it, x_var));
|
||||
test_uint(src, ecs_iter_get_var(&it, y_var));
|
||||
test_uint(tgt, ecs_iter_get_var(&it, this_var));
|
||||
test_uint(tgt, it.entities[0]);
|
||||
|
||||
test_bool(false, ecs_rule_next(&it));
|
||||
|
||||
ecs_rule_fini(r);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void RulesRecycled_has_recycled_id_from_pair(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, Tag);
|
||||
|
||||
ecs_entity_t src = recycled_id(world, "src");
|
||||
ecs_entity_t rel = recycled_id(world, "rel");
|
||||
ecs_entity_t tgt = recycled_id(world, "tgt");
|
||||
ecs_add_pair(world, src, rel, tgt);
|
||||
ecs_add_id(world, src, tgt);
|
||||
ecs_add(world, src, Tag);
|
||||
|
||||
ecs_rule_t *r = ecs_rule(world, {
|
||||
.expr = "$x($y, $z), $z($y), Tag($y)"
|
||||
});
|
||||
|
||||
test_assert(r != NULL);
|
||||
|
||||
int32_t x_var = ecs_rule_find_var(r, "x");
|
||||
test_assert(x_var != -1);
|
||||
int32_t y_var = ecs_rule_find_var(r, "y");
|
||||
test_assert(y_var != -1);
|
||||
int32_t z_var = ecs_rule_find_var(r, "z");
|
||||
test_assert(z_var != -1);
|
||||
|
||||
ecs_iter_t it = ecs_rule_iter(world, r);
|
||||
test_bool(true, ecs_rule_next(&it));
|
||||
test_uint(0, it.count);
|
||||
test_uint(ecs_pair(rel, tgt), ecs_field_id(&it, 1));
|
||||
test_uint(tgt, ecs_field_id(&it, 2));
|
||||
test_uint(Tag, ecs_field_id(&it, 3));
|
||||
test_uint(src, ecs_field_src(&it, 1));
|
||||
test_uint(src, ecs_field_src(&it, 2));
|
||||
test_uint(src, ecs_field_src(&it, 3));
|
||||
test_uint(rel, ecs_iter_get_var(&it, x_var));
|
||||
test_uint(src, ecs_iter_get_var(&it, y_var));
|
||||
test_uint(tgt, ecs_iter_get_var(&it, z_var));
|
||||
|
||||
test_bool(false, ecs_rule_next(&it));
|
||||
|
||||
ecs_rule_fini(r);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
400
engine/libs/flecs/test/addons/src/RulesScopes.c
Normal file
400
engine/libs/flecs/test/addons/src/RulesScopes.c
Normal file
@@ -0,0 +1,400 @@
|
||||
#include <addons.h>
|
||||
|
||||
void RulesScopes_term_w_not_scope_1_term(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, Root);
|
||||
ECS_TAG(world, TagA);
|
||||
|
||||
ecs_entity_t parent_1 = ecs_new(world, Root);
|
||||
ecs_add(world, parent_1, TagA);
|
||||
|
||||
ecs_entity_t parent_2 = ecs_new(world, Root);
|
||||
|
||||
ecs_rule_t *r = ecs_rule(world, {
|
||||
.expr = "Root, !{ TagA }"
|
||||
});
|
||||
test_assert(r != NULL);
|
||||
|
||||
{
|
||||
ecs_iter_t it = ecs_rule_iter(world, r);
|
||||
test_bool(true, ecs_rule_next(&it));
|
||||
test_uint(1, it.count);
|
||||
test_uint(Root, ecs_field_id(&it, 1));
|
||||
test_uint(0, ecs_field_src(&it, 1));
|
||||
test_bool(true, ecs_field_is_set(&it, 1));
|
||||
test_uint(parent_2, it.entities[0]);
|
||||
test_bool(false, ecs_rule_next(&it));
|
||||
}
|
||||
|
||||
ecs_rule_fini(r);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void RulesScopes_term_w_not_scope_2_terms(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, Root);
|
||||
ECS_TAG(world, TagA);
|
||||
ECS_TAG(world, TagB);
|
||||
|
||||
ecs_entity_t parent_1 = ecs_new(world, Root);
|
||||
ecs_add(world, parent_1, TagA);
|
||||
|
||||
ecs_entity_t parent_2 = ecs_new(world, Root);
|
||||
ecs_add(world, parent_2, TagB);
|
||||
|
||||
ecs_entity_t parent_3 = ecs_new(world, Root);
|
||||
ecs_add(world, parent_3, TagA);
|
||||
ecs_add(world, parent_3, TagB);
|
||||
|
||||
ecs_rule_t *r = ecs_rule(world, {
|
||||
.expr = "Root, !{ TagA, TagB }"
|
||||
});
|
||||
test_assert(r != NULL);
|
||||
|
||||
{
|
||||
ecs_iter_t it = ecs_rule_iter(world, r);
|
||||
test_bool(true, ecs_rule_next(&it));
|
||||
test_uint(1, it.count);
|
||||
test_uint(Root, ecs_field_id(&it, 1));
|
||||
test_uint(0, ecs_field_src(&it, 1));
|
||||
test_bool(true, ecs_field_is_set(&it, 1));
|
||||
test_uint(parent_1, it.entities[0]);
|
||||
|
||||
test_bool(true, ecs_rule_next(&it));
|
||||
test_uint(1, it.count);
|
||||
test_uint(Root, ecs_field_id(&it, 1));
|
||||
test_uint(0, ecs_field_src(&it, 1));
|
||||
test_bool(true, ecs_field_is_set(&it, 1));
|
||||
test_uint(parent_2, it.entities[0]);
|
||||
|
||||
test_bool(false, ecs_rule_next(&it));
|
||||
}
|
||||
|
||||
ecs_rule_fini(r);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void RulesScopes_term_w_not_scope_1_term_w_not(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, Root);
|
||||
ECS_TAG(world, TagA);
|
||||
|
||||
ecs_entity_t parent_1 = ecs_new(world, Root);
|
||||
ecs_add(world, parent_1, TagA);
|
||||
|
||||
ecs_new(world, Root);
|
||||
|
||||
ecs_rule_t *r = ecs_rule(world, {
|
||||
.expr = "Root, !{ !TagA }"
|
||||
});
|
||||
test_assert(r != NULL);
|
||||
|
||||
{
|
||||
ecs_iter_t it = ecs_rule_iter(world, r);
|
||||
test_bool(true, ecs_rule_next(&it));
|
||||
test_uint(1, it.count);
|
||||
test_uint(Root, ecs_field_id(&it, 1));
|
||||
test_uint(0, ecs_field_src(&it, 1));
|
||||
test_bool(true, ecs_field_is_set(&it, 1));
|
||||
test_uint(parent_1, it.entities[0]);
|
||||
test_bool(false, ecs_rule_next(&it));
|
||||
}
|
||||
|
||||
ecs_rule_fini(r);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void RulesScopes_term_w_not_scope_2_terms_w_not(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, Root);
|
||||
ECS_TAG(world, TagA);
|
||||
ECS_TAG(world, TagB);
|
||||
|
||||
ecs_entity_t parent_1 = ecs_new(world, Root);
|
||||
ecs_add(world, parent_1, TagA);
|
||||
|
||||
ecs_entity_t parent_2 = ecs_new(world, Root);
|
||||
ecs_add(world, parent_2, TagB);
|
||||
|
||||
ecs_entity_t parent_3 = ecs_new(world, Root);
|
||||
ecs_add(world, parent_3, TagA);
|
||||
ecs_add(world, parent_3, TagB);
|
||||
|
||||
ecs_rule_t *r = ecs_rule(world, {
|
||||
.expr = "Root, !{ TagA, !TagB }"
|
||||
});
|
||||
test_assert(r != NULL);
|
||||
|
||||
{
|
||||
ecs_iter_t it = ecs_rule_iter(world, r);
|
||||
test_bool(true, ecs_rule_next(&it));
|
||||
test_uint(1, it.count);
|
||||
test_uint(Root, ecs_field_id(&it, 1));
|
||||
test_uint(0, ecs_field_src(&it, 1));
|
||||
test_bool(true, ecs_field_is_set(&it, 1));
|
||||
test_uint(parent_2, it.entities[0]);
|
||||
|
||||
test_bool(true, ecs_rule_next(&it));
|
||||
test_uint(1, it.count);
|
||||
test_uint(Root, ecs_field_id(&it, 1));
|
||||
test_uint(0, ecs_field_src(&it, 1));
|
||||
test_bool(true, ecs_field_is_set(&it, 1));
|
||||
test_uint(parent_3, it.entities[0]);
|
||||
|
||||
test_bool(false, ecs_rule_next(&it));
|
||||
}
|
||||
|
||||
ecs_rule_fini(r);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void RulesScopes_term_w_not_scope_1_term_w_var(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, Root);
|
||||
|
||||
ecs_entity_t parent_1 = ecs_new(world, Root);
|
||||
ecs_new_w_pair(world, EcsChildOf, parent_1);
|
||||
ecs_new_w_pair(world, EcsChildOf, parent_1);
|
||||
|
||||
ecs_entity_t parent_2 = ecs_new(world, Root);
|
||||
ecs_new_w_pair(world, EcsChildOf, parent_2);
|
||||
|
||||
ecs_entity_t parent_3 = ecs_new(world, Root);
|
||||
|
||||
ecs_rule_t *r = ecs_rule(world, {
|
||||
.expr = "Root, !{ ChildOf($child, $this) }"
|
||||
});
|
||||
test_assert(r != NULL);
|
||||
|
||||
{
|
||||
ecs_iter_t it = ecs_rule_iter(world, r);
|
||||
test_bool(true, ecs_rule_next(&it));
|
||||
test_uint(1, it.count);
|
||||
test_uint(Root, ecs_field_id(&it, 1));
|
||||
test_uint(0, ecs_field_src(&it, 1));
|
||||
test_bool(true, ecs_field_is_set(&it, 1));
|
||||
test_uint(parent_3, it.entities[0]);
|
||||
test_bool(false, ecs_rule_next(&it));
|
||||
}
|
||||
|
||||
ecs_rule_fini(r);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void RulesScopes_term_w_not_scope_2_terms_w_var(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, Root);
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_entity_t parent_0 = ecs_new(world, Root);
|
||||
{
|
||||
ecs_entity_t child_1 = ecs_new_w_pair(world, EcsChildOf, parent_0);
|
||||
ecs_set(world, child_1, Position, {10, 20});
|
||||
ecs_entity_t child_2 = ecs_new_w_pair(world, EcsChildOf, parent_0);
|
||||
ecs_set(world, child_2, Position, {10, 20});
|
||||
}
|
||||
|
||||
ecs_entity_t parent_1 = ecs_new(world, Root);
|
||||
{
|
||||
ecs_entity_t child_1 = ecs_new_w_pair(world, EcsChildOf, parent_1);
|
||||
ecs_set(world, child_1, Position, {10, 20});
|
||||
ecs_new_w_pair(world, EcsChildOf, parent_1);
|
||||
}
|
||||
|
||||
ecs_entity_t parent_2 = ecs_new(world, Root);
|
||||
{
|
||||
ecs_new_w_pair(world, EcsChildOf, parent_2);
|
||||
ecs_new_w_pair(world, EcsChildOf, parent_2);
|
||||
}
|
||||
|
||||
ecs_rule_t *r = ecs_rule(world, {
|
||||
.expr = "Root, !{ ChildOf($child, $this), Position($child) }"
|
||||
});
|
||||
test_assert(r != NULL);
|
||||
|
||||
{
|
||||
ecs_iter_t it = ecs_rule_iter(world, r);
|
||||
test_bool(true, ecs_rule_next(&it));
|
||||
test_uint(1, it.count);
|
||||
test_uint(Root, ecs_field_id(&it, 1));
|
||||
test_uint(0, ecs_field_src(&it, 1));
|
||||
test_bool(true, ecs_field_is_set(&it, 1));
|
||||
test_uint(parent_2, it.entities[0]);
|
||||
test_bool(false, ecs_rule_next(&it));
|
||||
}
|
||||
|
||||
ecs_rule_fini(r);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void RulesScopes_term_w_not_scope_1_term_w_not_w_var(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, Root);
|
||||
|
||||
ecs_entity_t parent_0 = ecs_new(world, Root);
|
||||
{
|
||||
ecs_new_w_pair(world, EcsChildOf, parent_0);
|
||||
ecs_new_w_pair(world, EcsChildOf, parent_0);
|
||||
}
|
||||
|
||||
ecs_new(world, Root);
|
||||
|
||||
ecs_rule_t *r = ecs_rule(world, {
|
||||
.expr = "Root, !{ !ChildOf($child, $this) }"
|
||||
});
|
||||
test_assert(r != NULL);
|
||||
|
||||
{
|
||||
ecs_iter_t it = ecs_rule_iter(world, r);
|
||||
test_bool(true, ecs_rule_next(&it));
|
||||
test_uint(1, it.count);
|
||||
test_uint(Root, ecs_field_id(&it, 1));
|
||||
test_uint(0, ecs_field_src(&it, 1));
|
||||
test_bool(true, ecs_field_is_set(&it, 1));
|
||||
test_uint(parent_0, it.entities[0]);
|
||||
|
||||
test_bool(false, ecs_rule_next(&it));
|
||||
}
|
||||
|
||||
ecs_rule_fini(r);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void RulesScopes_term_w_not_scope_2_terms_w_not_w_var(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, Root);
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_entity_t parent_0 = ecs_new(world, Root);
|
||||
{
|
||||
ecs_entity_t child_1 = ecs_new_w_pair(world, EcsChildOf, parent_0);
|
||||
ecs_set(world, child_1, Position, {10, 20});
|
||||
ecs_entity_t child_2 = ecs_new_w_pair(world, EcsChildOf, parent_0);
|
||||
ecs_set(world, child_2, Position, {10, 20});
|
||||
}
|
||||
|
||||
ecs_entity_t parent_1 = ecs_new(world, Root);
|
||||
{
|
||||
ecs_entity_t child_1 = ecs_new_w_pair(world, EcsChildOf, parent_1);
|
||||
ecs_set(world, child_1, Position, {10, 20});
|
||||
ecs_new_w_pair(world, EcsChildOf, parent_1);
|
||||
}
|
||||
|
||||
ecs_entity_t parent_2 = ecs_new(world, Root);
|
||||
{
|
||||
ecs_new_w_pair(world, EcsChildOf, parent_2);
|
||||
ecs_new_w_pair(world, EcsChildOf, parent_2);
|
||||
}
|
||||
|
||||
ecs_rule_t *r = ecs_rule(world, {
|
||||
.expr = "Root, !{ ChildOf($child, $this), !Position($child) }"
|
||||
});
|
||||
test_assert(r != NULL);
|
||||
|
||||
{
|
||||
ecs_iter_t it = ecs_rule_iter(world, r);
|
||||
test_bool(true, ecs_rule_next(&it));
|
||||
test_uint(1, it.count);
|
||||
test_uint(Root, ecs_field_id(&it, 1));
|
||||
test_uint(0, ecs_field_src(&it, 1));
|
||||
test_bool(true, ecs_field_is_set(&it, 1));
|
||||
test_uint(parent_0, it.entities[0]);
|
||||
test_bool(false, ecs_rule_next(&it));
|
||||
}
|
||||
|
||||
ecs_rule_fini(r);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void RulesScopes_term_w_not_scope_2_terms_w_or(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, Root);
|
||||
ECS_TAG(world, TagA);
|
||||
ECS_TAG(world, TagB);
|
||||
|
||||
ecs_entity_t e1 = ecs_new(world, Root);
|
||||
ecs_add(world, e1, TagA);
|
||||
ecs_entity_t e2 = ecs_new(world, Root);
|
||||
ecs_add(world, e2, TagB);
|
||||
ecs_entity_t e3 = ecs_new(world, Root);
|
||||
ecs_add(world, e3, TagA);
|
||||
ecs_add(world, e3, TagB);
|
||||
ecs_entity_t e4 = ecs_new(world, Root);
|
||||
|
||||
ecs_rule_t *r = ecs_rule(world, {
|
||||
.expr = "Root, !{ TagA || TagB }"
|
||||
});
|
||||
test_assert(r != NULL);
|
||||
|
||||
{
|
||||
ecs_iter_t it = ecs_rule_iter(world, r);
|
||||
test_bool(true, ecs_rule_next(&it));
|
||||
test_uint(1, it.count);
|
||||
test_uint(Root, ecs_field_id(&it, 1));
|
||||
test_uint(0, ecs_field_src(&it, 1));
|
||||
test_bool(true, ecs_field_is_set(&it, 1));
|
||||
test_uint(e4, it.entities[0]);
|
||||
test_bool(false, ecs_rule_next(&it));
|
||||
}
|
||||
|
||||
ecs_rule_fini(r);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void RulesScopes_term_w_not_scope_3_terms_w_or(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, Root);
|
||||
ECS_TAG(world, TagA);
|
||||
ECS_TAG(world, TagB);
|
||||
ECS_TAG(world, TagC);
|
||||
|
||||
ecs_entity_t e1 = ecs_new(world, Root);
|
||||
ecs_add(world, e1, TagA);
|
||||
ecs_entity_t e2 = ecs_new(world, Root);
|
||||
ecs_add(world, e2, TagB);
|
||||
ecs_entity_t e3 = ecs_new(world, Root);
|
||||
ecs_add(world, e3, TagA);
|
||||
ecs_add(world, e3, TagB);
|
||||
ecs_entity_t e4 = ecs_new(world, Root);
|
||||
ecs_add(world, e4, TagC);
|
||||
ecs_entity_t e5 = ecs_new(world, Root);
|
||||
|
||||
ecs_rule_t *r = ecs_rule(world, {
|
||||
.expr = "Root, !{ TagA || TagB || TagC }"
|
||||
});
|
||||
test_assert(r != NULL);
|
||||
|
||||
{
|
||||
ecs_iter_t it = ecs_rule_iter(world, r);
|
||||
test_bool(true, ecs_rule_next(&it));
|
||||
test_uint(1, it.count);
|
||||
test_uint(Root, ecs_field_id(&it, 1));
|
||||
test_uint(0, ecs_field_src(&it, 1));
|
||||
test_bool(true, ecs_field_is_set(&it, 1));
|
||||
test_uint(e5, it.entities[0]);
|
||||
test_bool(false, ecs_rule_next(&it));
|
||||
}
|
||||
|
||||
ecs_rule_fini(r);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
5101
engine/libs/flecs/test/addons/src/RulesTransitive.c
Normal file
5101
engine/libs/flecs/test/addons/src/RulesTransitive.c
Normal file
File diff suppressed because it is too large
Load Diff
7381
engine/libs/flecs/test/addons/src/RulesVariables.c
Normal file
7381
engine/libs/flecs/test/addons/src/RulesVariables.c
Normal file
File diff suppressed because it is too large
Load Diff
1133
engine/libs/flecs/test/addons/src/Run.c
Normal file
1133
engine/libs/flecs/test/addons/src/Run.c
Normal file
File diff suppressed because it is too large
Load Diff
879
engine/libs/flecs/test/addons/src/Snapshot.c
Normal file
879
engine/libs/flecs/test/addons/src/Snapshot.c
Normal file
@@ -0,0 +1,879 @@
|
||||
#include <addons.h>
|
||||
|
||||
void Snapshot_simple_snapshot(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_entity_t e = ecs_set(world, 0, Position, {10, 20});
|
||||
test_assert(e != 0);
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
|
||||
ecs_snapshot_t *s = ecs_snapshot_take(world);
|
||||
|
||||
Position *p = ecs_get_mut(world, e, Position);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
p->x ++;
|
||||
p->y ++;
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
p = ecs_get_mut(world, e, Position);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_snapshot_after_new(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_entity_t e = ecs_new(world, Position);
|
||||
test_assert(e != 0);
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
|
||||
ecs_snapshot_t *s = ecs_snapshot_take(world);
|
||||
|
||||
ecs_entity_t e2 = ecs_new(world, Position);
|
||||
test_assert(e2 != 0);
|
||||
test_assert(ecs_has(world, e2, Position));
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
test_assert(ecs_is_alive(world, e));
|
||||
test_assert(!ecs_is_alive(world, e2));
|
||||
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
test_assert(ecs_new(world, 0) == e2);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_snapshot_after_delete(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_entity_t e = ecs_set(world, 0, Position, {10, 20});
|
||||
test_assert(e != 0);
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
|
||||
ecs_snapshot_t *s = ecs_snapshot_take(world);
|
||||
|
||||
ecs_delete(world, e);
|
||||
test_assert(!ecs_is_alive(world, e));
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
test_assert(ecs_is_alive(world, e));
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
|
||||
const Position *p = ecs_get(world, e, Position);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_snapshot_after_new_type(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ecs_entity_t e = ecs_set(world, 0, Position, {10, 20});
|
||||
test_assert(e != 0);
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
|
||||
ecs_snapshot_t *s = ecs_snapshot_take(world);
|
||||
|
||||
ecs_entity_t e2 = ecs_new(world, Position);
|
||||
ecs_add(world, e2, Velocity);
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
test_assert(ecs_is_alive(world, e));
|
||||
test_assert(!ecs_is_alive(world, e2));
|
||||
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_snapshot_after_add(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ecs_entity_t e = ecs_set(world, 0, Position, {10, 20});
|
||||
test_assert(e != 0);
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
|
||||
ecs_snapshot_t *s = ecs_snapshot_take(world);
|
||||
|
||||
ecs_add(world, e, Velocity);
|
||||
test_assert(ecs_has(world, e, Velocity));
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
test_assert(!ecs_has(world, e, Velocity));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_snapshot_after_remove(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ecs_entity_t e = ecs_new(world, Position);
|
||||
test_assert(e != 0);
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
|
||||
ecs_add(world, e, Velocity);
|
||||
test_assert(ecs_has(world, e, Velocity));
|
||||
|
||||
ecs_snapshot_t *s = ecs_snapshot_take(world);
|
||||
|
||||
ecs_remove(world, e, Velocity);
|
||||
test_assert(!ecs_has(world, e, Velocity));
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_snapshot_w_include_filter(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ecs_entity_t e1 = ecs_set(world, 0, Position, {10, 20});
|
||||
test_assert(e1 != 0);
|
||||
test_assert(ecs_has(world, e1, Position));
|
||||
|
||||
ecs_entity_t e2 = ecs_set(world, 0, Position, {15, 25});
|
||||
test_assert(e2 != 0);
|
||||
ecs_add(world, e2, Velocity);
|
||||
test_assert(ecs_has(world, e2, Position));
|
||||
test_assert(ecs_has(world, e2, Velocity));
|
||||
|
||||
ecs_entity_t e3 = ecs_set(world, 0, Velocity, {25, 35});
|
||||
test_assert(e3 != 0);
|
||||
test_assert(ecs_has(world, e3, Velocity));
|
||||
|
||||
ecs_filter_t f = ECS_FILTER_INIT;
|
||||
ecs_filter_init(world, &(ecs_filter_desc_t){
|
||||
.storage = &f,
|
||||
.terms = {{ ecs_id(Position) }}
|
||||
});
|
||||
|
||||
ecs_iter_t it = ecs_filter_iter(world, &f);
|
||||
ecs_snapshot_t *s = ecs_snapshot_take_w_iter(&it);
|
||||
|
||||
Position *p = ecs_get_mut(world, e1, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
p->x ++;
|
||||
p->y ++;
|
||||
|
||||
p = ecs_get_mut(world, e2, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 15);
|
||||
test_int(p->y, 25);
|
||||
|
||||
p->x ++;
|
||||
p->y ++;
|
||||
|
||||
Velocity *v = ecs_get_mut(world, e3, Velocity);
|
||||
test_assert(v != NULL);
|
||||
test_int(v->x, 25);
|
||||
test_int(v->y, 35);
|
||||
|
||||
v->x ++;
|
||||
v->y ++;
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
/* Restored */
|
||||
p = ecs_get_mut(world, e1, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
/* Restored */
|
||||
p = ecs_get_mut(world, e2, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 15);
|
||||
test_int(p->y, 25);
|
||||
|
||||
/* Not restored */
|
||||
v = ecs_get_mut(world, e3, Velocity);
|
||||
test_assert(v != NULL);
|
||||
test_int(v->x, 26);
|
||||
test_int(v->y, 36);
|
||||
|
||||
test_assert(ecs_new(world, 0) > e3);
|
||||
|
||||
ecs_filter_fini(&f);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_snapshot_w_exclude_filter(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ecs_entity_t e1 = ecs_set(world, 0, Position, {10, 20});
|
||||
test_assert(e1 != 0);
|
||||
test_assert(ecs_has(world, e1, Position));
|
||||
|
||||
ecs_entity_t e2 = ecs_set(world, 0, Position, {15, 25});
|
||||
test_assert(e2 != 0);
|
||||
ecs_add(world, e2, Velocity);
|
||||
test_assert(ecs_has(world, e2, Position));
|
||||
test_assert(ecs_has(world, e2, Velocity));
|
||||
|
||||
ecs_entity_t e3 = ecs_set(world, 0, Velocity, {25, 35});
|
||||
test_assert(e3 != 0);
|
||||
test_assert(ecs_has(world, e3, Velocity));
|
||||
|
||||
ecs_filter_t f = ECS_FILTER_INIT;
|
||||
ecs_filter_init(world, &(ecs_filter_desc_t){
|
||||
.storage = &f,
|
||||
.terms = {{ ecs_id(Position), .oper = EcsNot }}
|
||||
});
|
||||
|
||||
ecs_iter_t it = ecs_filter_iter(world, &f);
|
||||
ecs_snapshot_t *s = ecs_snapshot_take_w_iter(&it);
|
||||
|
||||
Position *p = ecs_get_mut(world, e1, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
p->x ++;
|
||||
p->y ++;
|
||||
|
||||
p = ecs_get_mut(world, e2, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 15);
|
||||
test_int(p->y, 25);
|
||||
|
||||
p->x ++;
|
||||
p->y ++;
|
||||
|
||||
Velocity *v = ecs_get_mut(world, e3, Velocity);
|
||||
test_assert(v != NULL);
|
||||
test_int(v->x, 25);
|
||||
test_int(v->y, 35);
|
||||
|
||||
v->x ++;
|
||||
v->y ++;
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
/* Not restored */
|
||||
p = ecs_get_mut(world, e1, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 11);
|
||||
test_int(p->y, 21);
|
||||
|
||||
/* Not restored */
|
||||
p = ecs_get_mut(world, e2, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 16);
|
||||
test_int(p->y, 26);
|
||||
|
||||
/* Restored */
|
||||
v = ecs_get_mut(world, e3, Velocity);
|
||||
test_assert(v != NULL);
|
||||
test_int(v->x, 25);
|
||||
test_int(v->y, 35);
|
||||
|
||||
test_assert(ecs_new(world, 0) > e3);
|
||||
|
||||
ecs_filter_fini(&f);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_snapshot_w_filter_after_new(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ecs_entity_t e1 = ecs_set(world, 0, Position, {1, 2});
|
||||
test_assert(e1 != 0);
|
||||
test_assert(ecs_has(world, e1, Position));
|
||||
|
||||
ecs_entity_t e2 = ecs_set(world, 0, Velocity, {3, 4});
|
||||
test_assert(e2 != 0);
|
||||
test_assert(ecs_has(world, e2, Velocity));
|
||||
|
||||
ecs_filter_t f = ECS_FILTER_INIT;
|
||||
ecs_filter_init(world, &(ecs_filter_desc_t){
|
||||
.storage = &f,
|
||||
.terms = {{ ecs_id(Position) }}
|
||||
});
|
||||
|
||||
ecs_iter_t it = ecs_filter_iter(world, &f);
|
||||
ecs_snapshot_t *s = ecs_snapshot_take_w_iter(&it);
|
||||
|
||||
ecs_set(world, e1, Position, {5, 6});
|
||||
ecs_set(world, e2, Velocity, {7, 8});
|
||||
|
||||
ecs_entity_t e3 = ecs_set(world, 0, Position, {33, 44});
|
||||
test_assert(e3 != 0);
|
||||
test_assert(ecs_has(world, e3, Position));
|
||||
|
||||
ecs_entity_t e4 = ecs_set(world, 0, Velocity, {34, 45});
|
||||
test_assert(e4 != 0);
|
||||
test_assert(ecs_has(world, e4, Velocity));
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
test_assert(ecs_has(world, e1, Position));
|
||||
const Position *p = ecs_get(world, e1, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 1);
|
||||
test_int(p->y, 2);
|
||||
|
||||
test_assert(ecs_has(world, e2, Velocity));
|
||||
const Velocity *v = ecs_get(world, e2, Velocity);
|
||||
test_assert(v != NULL);
|
||||
test_int(v->x, 7);
|
||||
test_int(v->y, 8);
|
||||
|
||||
test_assert(ecs_has(world, e3, Position));
|
||||
p = ecs_get(world, e3, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 33);
|
||||
test_int(p->y, 44);
|
||||
|
||||
test_assert(ecs_has(world, e4, Velocity));
|
||||
v = ecs_get(world, e4, Velocity);
|
||||
test_assert(p != NULL);
|
||||
test_int(v->x, 34);
|
||||
test_int(v->y, 45);
|
||||
|
||||
ecs_filter_fini(&f);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_snapshot_w_filter_after_delete(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ecs_entity_t e1 = ecs_set(world, 0, Position, {1, 2});
|
||||
test_assert(e1 != 0);
|
||||
test_assert(ecs_has(world, e1, Position));
|
||||
|
||||
ecs_entity_t e2 = ecs_set(world, 0, Velocity, {3, 4});
|
||||
test_assert(e2 != 0);
|
||||
test_assert(ecs_has(world, e2, Velocity));
|
||||
|
||||
ecs_entity_t e3 = ecs_set(world, 0, Position, {1, 2});
|
||||
test_assert(e3 != 0);
|
||||
test_assert(ecs_has(world, e3, Position));
|
||||
|
||||
ecs_entity_t e4 = ecs_set(world, 0, Velocity, {3, 4});
|
||||
test_assert(e4 != 0);
|
||||
test_assert(ecs_has(world, e4, Velocity));
|
||||
|
||||
ecs_filter_t f = ECS_FILTER_INIT;
|
||||
ecs_filter_init(world, &(ecs_filter_desc_t){
|
||||
.storage = &f,
|
||||
.terms = {{ ecs_id(Position) }}
|
||||
});
|
||||
|
||||
ecs_iter_t it = ecs_filter_iter(world, &f);
|
||||
ecs_snapshot_t *s = ecs_snapshot_take_w_iter(&it);
|
||||
|
||||
ecs_delete(world, e3);
|
||||
ecs_delete(world, e4);
|
||||
|
||||
test_assert(!ecs_is_alive(world, e3));
|
||||
test_assert(!ecs_is_alive(world, e4));
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
test_assert(ecs_is_alive(world, e1));
|
||||
test_assert(ecs_is_alive(world, e2));
|
||||
test_assert(ecs_is_alive(world, e3));
|
||||
test_assert(!ecs_is_alive(world, e4));
|
||||
|
||||
test_assert(ecs_has(world, e1, Position));
|
||||
test_assert(ecs_has(world, e2, Velocity));
|
||||
test_assert(ecs_has(world, e3, Position));
|
||||
|
||||
ecs_filter_fini(&f);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_snapshot_free_empty(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_snapshot_t *s = ecs_snapshot_take(world);
|
||||
test_assert(s != NULL);
|
||||
|
||||
ecs_snapshot_free(s);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_snapshot_free(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
test_assert( ecs_new(world, Position) != 0);
|
||||
test_assert( ecs_new(world, Velocity) != 0);
|
||||
|
||||
ecs_snapshot_t *s = ecs_snapshot_take(world);
|
||||
test_assert(s != NULL);
|
||||
|
||||
ecs_snapshot_free(s);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_snapshot_free_filtered(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
test_assert( ecs_new(world, Position) != 0);
|
||||
test_assert( ecs_new(world, Velocity) != 0);
|
||||
|
||||
ecs_filter_t f = ECS_FILTER_INIT;
|
||||
ecs_filter_init(world, &(ecs_filter_desc_t){
|
||||
.storage = &f,
|
||||
.terms = {{ ecs_id(Position) }}
|
||||
});
|
||||
|
||||
ecs_iter_t it = ecs_filter_iter(world, &f);
|
||||
ecs_snapshot_t *s = ecs_snapshot_take_w_iter(&it);
|
||||
test_assert(s != NULL);
|
||||
|
||||
ecs_snapshot_free(s);
|
||||
|
||||
ecs_filter_fini(&f);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_snapshot_free_filtered_w_dtor(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
ECS_COMPONENT(world, Mass);
|
||||
|
||||
ecs_entity_t e1 = ecs_entity_init(world, &(ecs_entity_desc_t){
|
||||
.name = "e1"
|
||||
});
|
||||
|
||||
ecs_entity_t e2 = ecs_entity_init(world, &(ecs_entity_desc_t){
|
||||
.name = "e2"
|
||||
});
|
||||
|
||||
ecs_entity_t e3 = ecs_entity_init(world, &(ecs_entity_desc_t){
|
||||
.name = "e3"
|
||||
});
|
||||
|
||||
ecs_add(world, e1, Position);
|
||||
ecs_add(world, e2, Position);
|
||||
ecs_add(world, e3, Position);
|
||||
|
||||
ecs_add(world, e1, Velocity);
|
||||
ecs_add(world, e2, Velocity);
|
||||
ecs_add(world, e3, Velocity);
|
||||
|
||||
ecs_add(world, e3, Mass);
|
||||
|
||||
ecs_filter_t f = ECS_FILTER_INIT;
|
||||
ecs_filter_init(world, &(ecs_filter_desc_t){
|
||||
.storage = &f,
|
||||
.terms = {{ ecs_id(Position) }, { ecs_id(Velocity) }}
|
||||
});
|
||||
|
||||
ecs_iter_t it = ecs_filter_iter(world, &f);
|
||||
ecs_snapshot_t *s = ecs_snapshot_take_w_iter(&it);
|
||||
test_assert(s != NULL);
|
||||
|
||||
ecs_snapshot_free(s);
|
||||
|
||||
ecs_filter_fini(&f);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static bool invoked = false;
|
||||
|
||||
static
|
||||
void Dummy(ecs_iter_t *it) {
|
||||
invoked = true;
|
||||
}
|
||||
|
||||
void Snapshot_snapshot_activate_table_w_filter(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_SYSTEM(world, Dummy, EcsOnUpdate, Position);
|
||||
|
||||
ecs_entity_t e = ecs_set(world, 0, Position, {0, 0});
|
||||
test_assert(e != 0);
|
||||
|
||||
ecs_filter_t f = ECS_FILTER_INIT;
|
||||
ecs_filter_init(world, &(ecs_filter_desc_t){
|
||||
.storage = &f,
|
||||
.terms = {{ ecs_id(Position) }}
|
||||
});
|
||||
|
||||
ecs_iter_t it = ecs_filter_iter(world, &f);
|
||||
ecs_snapshot_t *s = ecs_snapshot_take_w_iter(&it);
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
|
||||
ecs_progress(world, 0);
|
||||
test_bool(invoked, true);
|
||||
|
||||
ecs_filter_fini(&f);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_snapshot_copy(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_entity_t e = ecs_set(world, 0, Position, {10, 20});
|
||||
test_assert(e != 0);
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
|
||||
ecs_snapshot_t *s = ecs_snapshot_take(world);
|
||||
ecs_iter_t it = ecs_snapshot_iter(s);
|
||||
ecs_snapshot_t *s_copy = ecs_snapshot_take_w_iter(&it);
|
||||
ecs_snapshot_free(s);
|
||||
|
||||
Position *p = ecs_get_mut(world, e, Position);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
p->x ++;
|
||||
p->y ++;
|
||||
|
||||
ecs_snapshot_restore(world, s_copy);
|
||||
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
p = ecs_get_mut(world, e, Position);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_snapshot_get_ref_after_restore(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_entity_t e = ecs_set(world, 0, Position, {10, 20});
|
||||
test_assert(e != 0);
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
|
||||
ecs_ref_t ref = ecs_ref_init(world, e, Position);
|
||||
const Position *p = ecs_ref_get(world, &ref, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
ecs_snapshot_t *s = ecs_snapshot_take(world);
|
||||
|
||||
Position *p_mut = ecs_get_mut(world, e, Position);
|
||||
test_int(p_mut->x, 10);
|
||||
test_int(p_mut->y, 20);
|
||||
|
||||
p_mut->x ++;
|
||||
p_mut->y ++;
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
p = ecs_ref_get(world, &ref, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_new_after_snapshot(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ecs_entity_t e = ecs_set(world, 0, Position, {10, 20});
|
||||
test_assert(e != 0);
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
|
||||
ecs_snapshot_t *s = ecs_snapshot_take(world);
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
ecs_entity_t e2 = ecs_new(world, Position);
|
||||
test_assert(e2 != 0);
|
||||
test_assert(ecs_has(world, e2, Position));
|
||||
|
||||
ecs_add(world, e2, Velocity);
|
||||
test_assert(ecs_has(world, e2, Velocity));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_add_after_snapshot(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ecs_entity_t e = ecs_set(world, 0, Position, {10, 20});
|
||||
test_assert(e != 0);
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
|
||||
ecs_snapshot_t *s = ecs_snapshot_take(world);
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
ecs_add(world, e, Velocity);
|
||||
test_assert(ecs_has(world, e, Velocity));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_delete_after_snapshot(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_entity_t e = ecs_set(world, 0, Position, {10, 20});
|
||||
test_assert(e != 0);
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
|
||||
ecs_snapshot_t *s = ecs_snapshot_take(world);
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
ecs_delete(world, e);
|
||||
|
||||
test_assert(!ecs_is_alive(world, e));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_new_empty_after_snapshot(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ecs_entity_t e = ecs_set(world, 0, Position, {10, 20});
|
||||
test_assert(e != 0);
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
|
||||
ecs_snapshot_t *s = ecs_snapshot_take(world);
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
ecs_entity_t e2 = ecs_new(world, 0);
|
||||
test_assert(e2 != 0);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_set_after_snapshot(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ecs_entity_t e = ecs_set(world, 0, Position, {10, 20});
|
||||
test_assert(e != 0);
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
|
||||
ecs_snapshot_t *s = ecs_snapshot_take(world);
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
ecs_entity_t e2 = ecs_new(world, 0);
|
||||
test_assert(e2 != 0);
|
||||
|
||||
ecs_set_name(world, e2, "e2");
|
||||
test_assert(ecs_has_pair(world, e2, ecs_id(EcsIdentifier), EcsName));
|
||||
test_str(ecs_get_name(world, e2), "e2");
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_restore_recycled(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ecs_entity_t e = ecs_set(world, 0, Position, {10, 20});
|
||||
test_assert(e != 0);
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
|
||||
ecs_snapshot_t *s = ecs_snapshot_take(world);
|
||||
|
||||
ecs_delete(world, e);
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
ecs_entity_t e2 = ecs_new(world, 0);
|
||||
test_assert(e2 != 0);
|
||||
test_assert(e != e2);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static
|
||||
void SetP(ecs_iter_t *it) {
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
ecs_set_name(it->world, 0, "e2");
|
||||
}
|
||||
}
|
||||
|
||||
void Snapshot_snapshot_w_new_in_onset(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_entity_t e = ecs_set(world, 0, Position, {10, 20});
|
||||
test_assert(e != 0);
|
||||
test_assert(ecs_has(world, e, Position));
|
||||
|
||||
ECS_OBSERVER(world, SetP, EcsOnSet, Position);
|
||||
|
||||
ecs_snapshot_t *s = ecs_snapshot_take(world);
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
ecs_entity_t e2 = ecs_lookup(world, "e2");
|
||||
test_assert(e2 != 0);
|
||||
|
||||
ecs_entity_t e3 = ecs_set_name(world, 0, "e3");
|
||||
test_assert(e3 != 0);
|
||||
test_assert(e3 > e2);
|
||||
test_str(ecs_get_name(world, e3), "e3");
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static ecs_entity_t v_entity = 0;
|
||||
|
||||
static
|
||||
void CreateV(ecs_iter_t *it) {
|
||||
ecs_entity_t ecs_id(Velocity) = ecs_field_id(it, 2);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
v_entity = ecs_set(it->world, 0, Velocity, {3, 4});
|
||||
}
|
||||
}
|
||||
|
||||
void Snapshot_snapshot_w_new_in_onset_in_snapshot_table(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ecs_set(world, 0, Position, {10, 20});
|
||||
ecs_entity_t e2 = ecs_set(world, 0, Velocity, {1, 2});
|
||||
|
||||
ECS_OBSERVER(world, CreateV, EcsOnSet, Position, Velocity());
|
||||
|
||||
ecs_snapshot_t *s = ecs_snapshot_take(world);
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
const Velocity *v = ecs_get(world, e2, Velocity);
|
||||
test_assert(v != NULL);
|
||||
test_int(v->x, 1);
|
||||
test_int(v->y, 2);
|
||||
|
||||
v = ecs_get(world, v_entity, Velocity);
|
||||
test_assert(v != NULL);
|
||||
test_int(v->x, 3);
|
||||
test_int(v->y, 4);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Snapshot_snapshot_from_stage(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ecs_entity_t e1 = ecs_set(world, 0, Position, {1, 2});
|
||||
ecs_entity_t e2 = ecs_set(world, 0, Position, {3, 4});
|
||||
|
||||
ecs_readonly_begin(world);
|
||||
|
||||
ecs_world_t *stage = ecs_get_stage(world, 0);
|
||||
|
||||
ecs_snapshot_t *s = ecs_snapshot_take(stage);
|
||||
|
||||
ecs_delete(stage, e1);
|
||||
ecs_delete(stage, e2);
|
||||
|
||||
ecs_readonly_end(world);
|
||||
|
||||
test_assert(!ecs_is_alive(world, e1));
|
||||
test_assert(!ecs_is_alive(world, e2));
|
||||
|
||||
ecs_snapshot_restore(world, s);
|
||||
|
||||
const Position *p = ecs_get(world, e1, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 1);
|
||||
test_int(p->y, 2);
|
||||
|
||||
p = ecs_get(world, e2, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 3);
|
||||
test_int(p->y, 4);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
314
engine/libs/flecs/test/addons/src/Stats.c
Normal file
314
engine/libs/flecs/test/addons/src/Stats.c
Normal file
@@ -0,0 +1,314 @@
|
||||
#include <addons.h>
|
||||
|
||||
#define test_delta(prev, cur, field, value)\
|
||||
test_int(value, (cur)->field - (prev)->field);\
|
||||
(prev)->field = (cur)->field
|
||||
|
||||
void Stats_get_world_stats(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_world_stats_t stats = {0};
|
||||
ecs_world_stats_get(world, &stats);
|
||||
|
||||
test_int(stats.t, 1);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Stats_get_pipeline_stats_before_progress_mini_world(void) {
|
||||
ecs_world_t *world = ecs_mini();
|
||||
|
||||
ECS_IMPORT(world, FlecsPipeline);
|
||||
|
||||
ecs_entity_t pipeline = ecs_get_pipeline(world);
|
||||
test_assert(pipeline != 0);
|
||||
|
||||
ecs_pipeline_stats_t stats = {0};
|
||||
test_bool(ecs_pipeline_stats_get(world, pipeline, &stats), false);
|
||||
|
||||
test_assert(ecs_vec_count(&stats.systems) == 0);
|
||||
test_assert(ecs_map_count(&stats.system_stats) == 0);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Stats_get_pipeline_stats_before_progress(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_entity_t pipeline = ecs_get_pipeline(world);
|
||||
test_assert(pipeline != 0);
|
||||
|
||||
ecs_pipeline_stats_t stats = {0};
|
||||
test_bool(ecs_pipeline_stats_get(world, pipeline, &stats), true);
|
||||
|
||||
test_assert(ecs_vec_count(&stats.systems) == 0);
|
||||
test_assert(ecs_map_count(&stats.system_stats) != 0); /* Inactive systems */
|
||||
|
||||
ecs_pipeline_stats_fini(&stats);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Stats_get_pipeline_stats_after_progress_no_systems(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_entity_t pipeline = ecs_get_pipeline(world);
|
||||
test_assert(pipeline != 0);
|
||||
|
||||
ecs_progress(world, 0);
|
||||
|
||||
ecs_pipeline_stats_t stats = {0};
|
||||
test_bool(ecs_pipeline_stats_get(world, pipeline, &stats), true);
|
||||
|
||||
test_int(ecs_vec_count(&stats.systems), 1);
|
||||
test_int(ecs_vec_get_t(&stats.systems, ecs_entity_t, 0)[0], 0); /* merge */
|
||||
|
||||
test_assert(ecs_map_count(&stats.system_stats) != 0); /* Inactive systems */
|
||||
|
||||
ecs_pipeline_stats_fini(&stats);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static void FooSys(ecs_iter_t *it) { }
|
||||
static void BarSys(ecs_iter_t *it) { }
|
||||
|
||||
void Stats_get_pipeline_stats_after_progress_1_system(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_SYSTEM(world, FooSys, EcsOnUpdate, 0);
|
||||
|
||||
ecs_entity_t pipeline = ecs_get_pipeline(world);
|
||||
test_assert(pipeline != 0);
|
||||
|
||||
ecs_progress(world, 0);
|
||||
|
||||
ecs_pipeline_stats_t stats = {0};
|
||||
test_bool(ecs_pipeline_stats_get(world, pipeline, &stats), true);
|
||||
|
||||
test_int(ecs_vec_count(&stats.systems), 2);
|
||||
test_int(ecs_vec_get_t(&stats.systems, ecs_entity_t, 0)[0], ecs_id(FooSys));
|
||||
test_int(ecs_vec_get_t(&stats.systems, ecs_entity_t, 0)[1], 0); /* merge */
|
||||
|
||||
test_assert(ecs_map_count(&stats.system_stats) != 0);
|
||||
ecs_system_stats_t *sys_stats = ecs_map_get_deref(
|
||||
&stats.system_stats, ecs_system_stats_t, ecs_id(FooSys));
|
||||
test_assert(sys_stats != NULL);
|
||||
test_int(sys_stats->query.t, 1);
|
||||
test_int(sys_stats->invoke_count.counter.value[1], 1);
|
||||
|
||||
ecs_progress(world, 0);
|
||||
|
||||
test_bool(ecs_pipeline_stats_get(world, pipeline, &stats), true);
|
||||
test_int(sys_stats->query.t, 2);
|
||||
test_int(sys_stats->invoke_count.counter.value[2], 2);
|
||||
|
||||
ecs_pipeline_stats_fini(&stats);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Stats_get_pipeline_stats_after_progress_1_inactive_system(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_SYSTEM(world, FooSys, EcsOnUpdate, Position); // no matching entities
|
||||
|
||||
ecs_entity_t pipeline = ecs_get_pipeline(world);
|
||||
test_assert(pipeline != 0);
|
||||
|
||||
ecs_progress(world, 0);
|
||||
|
||||
ecs_pipeline_stats_t stats = {0};
|
||||
test_bool(ecs_pipeline_stats_get(world, pipeline, &stats), true);
|
||||
|
||||
test_int(ecs_vec_count(&stats.systems), 1);
|
||||
test_int(ecs_vec_get_t(&stats.systems, ecs_entity_t, 0)[0], 0); /* merge */
|
||||
|
||||
test_assert(ecs_map_count(&stats.system_stats) != 0);
|
||||
ecs_system_stats_t *sys_stats = ecs_map_get_deref(
|
||||
&stats.system_stats, ecs_system_stats_t, ecs_id(FooSys));
|
||||
test_assert(sys_stats != NULL);
|
||||
test_int(sys_stats->query.t, 1);
|
||||
test_int(sys_stats->invoke_count.counter.value[1], 0);
|
||||
|
||||
ecs_progress(world, 0);
|
||||
|
||||
test_bool(ecs_pipeline_stats_get(world, pipeline, &stats), true);
|
||||
test_int(sys_stats->query.t, 2);
|
||||
test_int(sys_stats->invoke_count.counter.value[2], 0);
|
||||
|
||||
ecs_pipeline_stats_fini(&stats);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Stats_get_pipeline_stats_after_progress_2_systems(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_SYSTEM(world, FooSys, EcsOnUpdate, 0);
|
||||
ECS_SYSTEM(world, BarSys, EcsOnUpdate, 0);
|
||||
|
||||
ecs_entity_t pipeline = ecs_get_pipeline(world);
|
||||
test_assert(pipeline != 0);
|
||||
|
||||
ecs_progress(world, 0);
|
||||
|
||||
ecs_pipeline_stats_t stats = {0};
|
||||
test_bool(ecs_pipeline_stats_get(world, pipeline, &stats), true);
|
||||
|
||||
test_int(ecs_vec_count(&stats.systems), 3);
|
||||
test_int(ecs_vec_get_t(&stats.systems, ecs_entity_t, 0)[0], ecs_id(FooSys));
|
||||
test_int(ecs_vec_get_t(&stats.systems, ecs_entity_t, 0)[1], ecs_id(BarSys));
|
||||
test_int(ecs_vec_get_t(&stats.systems, ecs_entity_t, 0)[2], 0); /* merge */
|
||||
|
||||
test_assert(ecs_map_count(&stats.system_stats) != 0);
|
||||
ecs_system_stats_t *sys_foo_stats = ecs_map_get_deref(
|
||||
&stats.system_stats, ecs_system_stats_t, ecs_id(FooSys));
|
||||
test_assert(sys_foo_stats != NULL);
|
||||
test_int(sys_foo_stats->query.t, 1);
|
||||
test_int(sys_foo_stats->invoke_count.counter.value[1], 1);
|
||||
|
||||
ecs_system_stats_t *sys_bar_stats = ecs_map_get_deref(
|
||||
&stats.system_stats, ecs_system_stats_t, ecs_id(BarSys));
|
||||
test_assert(sys_bar_stats != NULL);
|
||||
test_int(sys_bar_stats->query.t, 1);
|
||||
test_int(sys_bar_stats->invoke_count.counter.value[1], 1);
|
||||
|
||||
ecs_progress(world, 0);
|
||||
|
||||
ecs_run(world, ecs_id(BarSys), 0, 0);
|
||||
|
||||
test_bool(ecs_pipeline_stats_get(world, pipeline, &stats), true);
|
||||
test_int(sys_foo_stats->query.t, 2);
|
||||
test_int(sys_foo_stats->invoke_count.counter.value[2], 2);
|
||||
|
||||
test_int(sys_bar_stats->query.t, 2);
|
||||
test_int(sys_bar_stats->invoke_count.counter.value[2], 3);
|
||||
|
||||
ecs_pipeline_stats_fini(&stats);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Stats_get_pipeline_stats_after_progress_2_systems_one_merge(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ecs_new(world, Position); // Make sure systems are active
|
||||
|
||||
ECS_SYSTEM(world, FooSys, EcsOnUpdate, [out] Position());
|
||||
ECS_SYSTEM(world, BarSys, EcsOnUpdate, Position);
|
||||
|
||||
ecs_entity_t pipeline = ecs_get_pipeline(world);
|
||||
test_assert(pipeline != 0);
|
||||
|
||||
ecs_progress(world, 0);
|
||||
|
||||
ecs_pipeline_stats_t stats = {0};
|
||||
test_bool(ecs_pipeline_stats_get(world, pipeline, &stats), true);
|
||||
|
||||
test_int(ecs_vec_count(&stats.systems), 4);
|
||||
test_int(ecs_vec_get_t(&stats.systems, ecs_entity_t, 0)[0], ecs_id(FooSys));
|
||||
test_int(ecs_vec_get_t(&stats.systems, ecs_entity_t, 0)[1], 0); /* merge */
|
||||
test_int(ecs_vec_get_t(&stats.systems, ecs_entity_t, 0)[2], ecs_id(BarSys));
|
||||
test_int(ecs_vec_get_t(&stats.systems, ecs_entity_t, 0)[3], 0); /* merge */
|
||||
|
||||
test_assert(ecs_map_count(&stats.system_stats) != 0);
|
||||
ecs_system_stats_t *sys_foo_stats = ecs_map_get_deref(
|
||||
&stats.system_stats, ecs_system_stats_t, ecs_id(FooSys));
|
||||
test_assert(sys_foo_stats != NULL);
|
||||
test_int(sys_foo_stats->query.t, 1);
|
||||
test_int(sys_foo_stats->invoke_count.counter.value[1], 1);
|
||||
|
||||
ecs_system_stats_t *sys_bar_stats = ecs_map_get_deref(
|
||||
&stats.system_stats, ecs_system_stats_t, ecs_id(BarSys));
|
||||
test_assert(sys_bar_stats != NULL);
|
||||
test_int(sys_bar_stats->query.t, 1);
|
||||
test_int(sys_bar_stats->invoke_count.counter.value[1], 1);
|
||||
|
||||
ecs_progress(world, 0);
|
||||
|
||||
test_bool(ecs_pipeline_stats_get(world, pipeline, &stats), true);
|
||||
test_int(sys_foo_stats->query.t, 2);
|
||||
test_int(sys_foo_stats->invoke_count.counter.value[2], 2);
|
||||
|
||||
test_int(sys_bar_stats->query.t, 2);
|
||||
test_int(sys_bar_stats->invoke_count.counter.value[2], 2);
|
||||
|
||||
ecs_pipeline_stats_fini(&stats);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Stats_get_pipeline_stats_w_task_system(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_SYSTEM(world, FooSys, EcsOnUpdate, 0);
|
||||
|
||||
ecs_entity_t pipeline = ecs_get_pipeline(world);
|
||||
test_assert(pipeline != 0);
|
||||
|
||||
ecs_pipeline_stats_t stats = {0};
|
||||
test_bool(ecs_pipeline_stats_get(world, pipeline, &stats), true);
|
||||
test_assert(ecs_map_count(&stats.system_stats) != 0); /* Inactive systems */
|
||||
test_int(ecs_vec_count(&stats.systems), 0);
|
||||
|
||||
ecs_pipeline_stats_fini(&stats);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Stats_get_entity_count(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_world_stats_t stats = {0};
|
||||
ecs_world_stats_get(world, &stats);
|
||||
|
||||
float count;
|
||||
float prev = count = stats.entities.count.gauge.avg[stats.t];
|
||||
test_assert(count != 0);
|
||||
|
||||
ecs_entity_t e = ecs_new_id(world);
|
||||
|
||||
ecs_world_stats_get(world, &stats);
|
||||
count = stats.entities.count.gauge.avg[stats.t];
|
||||
test_int(count - prev, 1);
|
||||
|
||||
ecs_delete(world, e);
|
||||
|
||||
prev = count;
|
||||
ecs_world_stats_get(world, &stats);
|
||||
count = stats.entities.count.gauge.avg[stats.t];
|
||||
test_int(count - prev, -1);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Stats_get_not_alive_entity_count(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_world_stats_t stats = {0};
|
||||
ecs_world_stats_get(world, &stats);
|
||||
|
||||
float count;
|
||||
float prev = count = stats.entities.not_alive_count.gauge.avg[stats.t];
|
||||
test_int(count, 0);
|
||||
|
||||
ecs_entity_t e = ecs_new_id(world);
|
||||
|
||||
prev = count;
|
||||
ecs_world_stats_get(world, &stats);
|
||||
count = stats.entities.not_alive_count.gauge.avg[stats.t];
|
||||
test_int(count - prev, 0);
|
||||
|
||||
ecs_delete(world, e);
|
||||
|
||||
prev = count;
|
||||
ecs_world_stats_get(world, &stats);
|
||||
count = stats.entities.not_alive_count.gauge.avg[stats.t];
|
||||
test_int(count - prev, 1);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
715
engine/libs/flecs/test/addons/src/SystemCascade.c
Normal file
715
engine/libs/flecs/test/addons/src/SystemCascade.c
Normal file
@@ -0,0 +1,715 @@
|
||||
#include <addons.h>
|
||||
|
||||
static
|
||||
void Iter(ecs_iter_t *it) {
|
||||
Position *p = ecs_field(it, Position, 1);
|
||||
Position *p_parent = ecs_field(it, Position, 2);
|
||||
|
||||
test_assert(!p_parent || !ecs_field_is_self(it, 2));
|
||||
|
||||
probe_iter(it);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
p[i].x ++;
|
||||
p[i].y ++;
|
||||
|
||||
if (p_parent) {
|
||||
p[i].x += p_parent->x;
|
||||
p[i].y += p_parent->y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SystemCascade_cascade_depth_1(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_ENTITY(world, e1, Position);
|
||||
ECS_ENTITY(world, e2, Position);
|
||||
ECS_ENTITY(world, e3, Position);
|
||||
ECS_ENTITY(world, e4, Position);
|
||||
|
||||
ECS_SYSTEM(world, Iter, EcsOnUpdate, Position, ?Position(parent|cascade));
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = Iter,
|
||||
.query.filter.instanced = true
|
||||
});
|
||||
|
||||
ecs_set(world, e1, Position, {1, 2});
|
||||
ecs_set(world, e2, Position, {1, 2});
|
||||
ecs_set(world, e3, Position, {1, 2});
|
||||
ecs_set(world, e4, Position, {1, 2});
|
||||
|
||||
ecs_add_pair(world, e3, EcsChildOf, e1);
|
||||
ecs_add_pair(world, e4, EcsChildOf, e2);
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(ctx.count, 4);
|
||||
test_int(ctx.invoked, 3);
|
||||
test_int(ctx.system, Iter);
|
||||
test_int(ctx.term_count, 2);
|
||||
test_null(ctx.param);
|
||||
|
||||
probe_has_entity(&ctx, e1);
|
||||
probe_has_entity(&ctx, e2);
|
||||
probe_has_entity(&ctx, e3);
|
||||
probe_has_entity(&ctx, e4);
|
||||
|
||||
test_int(ctx.c[0][0], ecs_id(Position));
|
||||
test_int(ctx.s[0][0], 0);
|
||||
|
||||
const Position *p = ecs_get(world, e1, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 2);
|
||||
test_int(p->y, 3);
|
||||
|
||||
p = ecs_get(world, e2, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 2);
|
||||
test_int(p->y, 3);
|
||||
|
||||
p = ecs_get(world, e3, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 4);
|
||||
test_int(p->y, 6);
|
||||
|
||||
p = ecs_get(world, e4, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 4);
|
||||
test_int(p->y, 6);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void SystemCascade_cascade_depth_2(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_ENTITY(world, e1, Position);
|
||||
ECS_ENTITY(world, e2, Position);
|
||||
ECS_ENTITY(world, e3, Position);
|
||||
ECS_ENTITY(world, e4, Position);
|
||||
ECS_ENTITY(world, e5, Position);
|
||||
ECS_ENTITY(world, e6, Position);
|
||||
|
||||
ECS_SYSTEM(world, Iter, EcsOnUpdate, Position, ?Position(parent|cascade));
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = Iter,
|
||||
.query.filter.instanced = true
|
||||
});
|
||||
|
||||
ecs_set(world, e1, Position, {1, 2});
|
||||
ecs_set(world, e2, Position, {1, 2});
|
||||
ecs_set(world, e3, Position, {1, 2});
|
||||
ecs_set(world, e4, Position, {1, 2});
|
||||
ecs_set(world, e5, Position, {1, 2});
|
||||
ecs_set(world, e6, Position, {1, 2});
|
||||
|
||||
ecs_add_pair(world, e3, EcsChildOf, e1); /* depth 1 */
|
||||
ecs_add_pair(world, e4, EcsChildOf, e2); /* depth 1 */
|
||||
ecs_add_pair(world, e5, EcsChildOf, e3); /* depth 2 */
|
||||
ecs_add_pair(world, e6, EcsChildOf, e4); /* depth 2 */
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(ctx.count, 6);
|
||||
test_int(ctx.invoked, 5);
|
||||
test_int(ctx.system, Iter);
|
||||
test_int(ctx.term_count, 2);
|
||||
test_null(ctx.param);
|
||||
|
||||
test_assert((ctx.e[0] == e1 && ctx.e[1] == e2) || (ctx.e[0] == e2 && ctx.e[1] == e1));
|
||||
test_assert((ctx.e[2] == e3 && ctx.e[3] == e4) || (ctx.e[2] == e4 && ctx.e[3] == e3));
|
||||
test_assert((ctx.e[4] == e5 && ctx.e[5] == e6) || (ctx.e[4] == e6 && ctx.e[5] == e5));
|
||||
|
||||
test_int(ctx.c[0][0], ecs_id(Position));
|
||||
test_int(ctx.s[0][0], 0);
|
||||
|
||||
const Position *p = ecs_get(world, e1, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 2);
|
||||
test_int(p->y, 3);
|
||||
|
||||
p = ecs_get(world, e2, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 2);
|
||||
test_int(p->y, 3);
|
||||
|
||||
p = ecs_get(world, e3, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 4);
|
||||
test_int(p->y, 6);
|
||||
|
||||
p = ecs_get(world, e4, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 4);
|
||||
test_int(p->y, 6);
|
||||
|
||||
p = ecs_get(world, e5, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 6);
|
||||
test_int(p->y, 9);
|
||||
|
||||
p = ecs_get(world, e6, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 6);
|
||||
test_int(p->y, 9);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void SystemCascade_cascade_depth_2_new_syntax(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_ENTITY(world, e1, Position);
|
||||
ECS_ENTITY(world, e2, Position);
|
||||
ECS_ENTITY(world, e3, Position);
|
||||
ECS_ENTITY(world, e4, Position);
|
||||
ECS_ENTITY(world, e5, Position);
|
||||
ECS_ENTITY(world, e6, Position);
|
||||
|
||||
ECS_SYSTEM(world, Iter, EcsOnUpdate, Position, ?Position(cascade(ChildOf)));
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = Iter,
|
||||
.query.filter.instanced = true
|
||||
});
|
||||
|
||||
ecs_set(world, e1, Position, {1, 2});
|
||||
ecs_set(world, e2, Position, {1, 2});
|
||||
ecs_set(world, e3, Position, {1, 2});
|
||||
ecs_set(world, e4, Position, {1, 2});
|
||||
ecs_set(world, e5, Position, {1, 2});
|
||||
ecs_set(world, e6, Position, {1, 2});
|
||||
|
||||
ecs_add_pair(world, e3, EcsChildOf, e1); /* depth 1 */
|
||||
ecs_add_pair(world, e4, EcsChildOf, e2); /* depth 1 */
|
||||
ecs_add_pair(world, e5, EcsChildOf, e3); /* depth 2 */
|
||||
ecs_add_pair(world, e6, EcsChildOf, e4); /* depth 2 */
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(ctx.count, 6);
|
||||
test_int(ctx.invoked, 5);
|
||||
test_int(ctx.system, Iter);
|
||||
test_int(ctx.term_count, 2);
|
||||
test_null(ctx.param);
|
||||
|
||||
test_assert((ctx.e[0] == e1 && ctx.e[1] == e2) || (ctx.e[0] == e2 && ctx.e[1] == e1));
|
||||
test_assert((ctx.e[2] == e3 && ctx.e[3] == e4) || (ctx.e[2] == e4 && ctx.e[3] == e3));
|
||||
test_assert((ctx.e[4] == e5 && ctx.e[5] == e6) || (ctx.e[4] == e6 && ctx.e[5] == e5));
|
||||
|
||||
test_int(ctx.c[0][0], ecs_id(Position));
|
||||
test_int(ctx.s[0][0], 0);
|
||||
|
||||
const Position *p = ecs_get(world, e1, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 2);
|
||||
test_int(p->y, 3);
|
||||
|
||||
p = ecs_get(world, e2, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 2);
|
||||
test_int(p->y, 3);
|
||||
|
||||
p = ecs_get(world, e3, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 4);
|
||||
test_int(p->y, 6);
|
||||
|
||||
p = ecs_get(world, e4, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 4);
|
||||
test_int(p->y, 6);
|
||||
|
||||
p = ecs_get(world, e5, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 6);
|
||||
test_int(p->y, 9);
|
||||
|
||||
p = ecs_get(world, e6, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 6);
|
||||
test_int(p->y, 9);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static
|
||||
void AddParent(ecs_iter_t *it) {
|
||||
Position *p = ecs_field(it, Position, 1);
|
||||
Position *p_parent = ecs_field(it, Position, 2);
|
||||
|
||||
test_assert(!p_parent || !ecs_field_is_self(it, 2));
|
||||
|
||||
probe_iter(it);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
if (p_parent) {
|
||||
p[i].x += p_parent->x;
|
||||
p[i].y += p_parent->y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SystemCascade_add_after_match(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_ENTITY(world, e1, Position);
|
||||
ECS_ENTITY(world, e2, Position);
|
||||
ECS_ENTITY(world, e3, Position);
|
||||
ECS_ENTITY(world, e4, Position);
|
||||
|
||||
ECS_SYSTEM(world, AddParent, EcsOnUpdate, Position, ?Position(parent|cascade));
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = AddParent,
|
||||
.query.filter.instanced = true
|
||||
});
|
||||
|
||||
ecs_entity_t parent = ecs_new(world, 0);
|
||||
ecs_set(world, e1, Position, {1, 2});
|
||||
ecs_set(world, e2, Position, {1, 2});
|
||||
ecs_set(world, e3, Position, {1, 2});
|
||||
ecs_set(world, e4, Position, {1, 2});
|
||||
|
||||
ecs_add_pair(world, e3, EcsChildOf, parent); /* depth 1 */
|
||||
ecs_add_pair(world, e4, EcsChildOf, parent); /* depth 1 */
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
/* Before adding Position to parent, it wasn't being considered for the
|
||||
* column(parent|cascade), so tables could have been ordered randomly. Make sure
|
||||
* that queries can handle changes to depth after all tables are matched */
|
||||
ecs_set(world, parent, Position, {1, 2});
|
||||
|
||||
ecs_os_zeromem(&ctx);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(ctx.count, 5);
|
||||
test_int(ctx.invoked, 3);
|
||||
test_int(ctx.system, AddParent);
|
||||
test_int(ctx.term_count, 2);
|
||||
test_null(ctx.param);
|
||||
|
||||
test_assert(ctx.e[0] == e1 || ctx.e[1] == e1 || ctx.e[2] == e1);
|
||||
test_assert(ctx.e[0] == e2 || ctx.e[1] == e2 || ctx.e[2] == e2);
|
||||
test_assert(ctx.e[0] == parent || ctx.e[1] == parent || ctx.e[2] == parent);
|
||||
test_assert(ctx.e[3] == e3 || ctx.e[4] == e3);
|
||||
test_assert(ctx.e[3] == e4 || ctx.e[4] == e4);
|
||||
|
||||
test_int(ctx.c[0][0], ecs_id(Position));
|
||||
test_int(ctx.s[0][0], 0);
|
||||
|
||||
const Position *p = ecs_get(world, e1, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 1);
|
||||
test_int(p->y, 2);
|
||||
|
||||
p = ecs_get(world, e2, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 1);
|
||||
test_int(p->y, 2);
|
||||
|
||||
p = ecs_get(world, e3, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 2);
|
||||
test_int(p->y, 4);
|
||||
|
||||
p = ecs_get(world, e4, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 2);
|
||||
test_int(p->y, 4);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void SystemCascade_adopt_after_match(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_ENTITY(world, e1, Position);
|
||||
ECS_ENTITY(world, e2, Position);
|
||||
ECS_ENTITY(world, e3, Position);
|
||||
ECS_ENTITY(world, e4, Position);
|
||||
|
||||
ECS_SYSTEM(world, AddParent, EcsOnUpdate, Position, ?Position(parent|cascade));
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = AddParent,
|
||||
.query.filter.instanced = true
|
||||
});
|
||||
|
||||
ecs_entity_t parent = ecs_set(world, 0, Position, {1, 2});
|
||||
ecs_set(world, e1, Position, {1, 2});
|
||||
ecs_set(world, e2, Position, {1, 2});
|
||||
ecs_set(world, e3, Position, {1, 2});
|
||||
ecs_set(world, e4, Position, {1, 2});
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
ecs_add_pair(world, e3, EcsChildOf, parent);
|
||||
ecs_add_pair(world, e4, EcsChildOf, parent);
|
||||
|
||||
ecs_os_zeromem(&ctx);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(ctx.count, 5);
|
||||
test_int(ctx.invoked, 3);
|
||||
test_int(ctx.system, AddParent);
|
||||
test_int(ctx.term_count, 2);
|
||||
test_null(ctx.param);
|
||||
|
||||
test_int(ctx.e[0], e1);
|
||||
test_int(ctx.e[1], e2);
|
||||
test_int(ctx.e[2], parent);
|
||||
test_int(ctx.e[3], e3);
|
||||
test_int(ctx.e[4], e4);
|
||||
test_int(ctx.c[0][0], ecs_id(Position));
|
||||
test_int(ctx.s[0][0], 0);
|
||||
|
||||
const Position *p = ecs_get(world, e1, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 1);
|
||||
test_int(p->y, 2);
|
||||
|
||||
p = ecs_get(world, e2, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 1);
|
||||
test_int(p->y, 2);
|
||||
|
||||
p = ecs_get(world, e3, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 2);
|
||||
test_int(p->y, 4);
|
||||
|
||||
p = ecs_get(world, e4, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 2);
|
||||
test_int(p->y, 4);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void SystemCascade_custom_relation_cascade_depth_1(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_ENTITY(world, Rel, Traversable);
|
||||
|
||||
ECS_ENTITY(world, e1, Position);
|
||||
ECS_ENTITY(world, e2, Position);
|
||||
ECS_ENTITY(world, e3, Position);
|
||||
ECS_ENTITY(world, e4, Position);
|
||||
|
||||
ECS_SYSTEM(world, Iter, EcsOnUpdate, Position, ?Position(cascade(Rel)));
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = Iter,
|
||||
.query.filter.instanced = true
|
||||
});
|
||||
|
||||
ecs_set(world, e1, Position, {1, 2});
|
||||
ecs_set(world, e2, Position, {1, 2});
|
||||
ecs_set(world, e3, Position, {1, 2});
|
||||
ecs_set(world, e4, Position, {1, 2});
|
||||
|
||||
ecs_add_pair(world, e3, Rel, e1);
|
||||
ecs_add_pair(world, e4, Rel, e2);
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(ctx.count, 4);
|
||||
test_int(ctx.invoked, 3);
|
||||
test_int(ctx.system, Iter);
|
||||
test_int(ctx.term_count, 2);
|
||||
test_null(ctx.param);
|
||||
|
||||
probe_has_entity(&ctx, e1);
|
||||
probe_has_entity(&ctx, e2);
|
||||
probe_has_entity(&ctx, e3);
|
||||
probe_has_entity(&ctx, e4);
|
||||
|
||||
test_int(ctx.c[0][0], ecs_id(Position));
|
||||
test_int(ctx.s[0][0], 0);
|
||||
|
||||
const Position *p = ecs_get(world, e1, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 2);
|
||||
test_int(p->y, 3);
|
||||
|
||||
p = ecs_get(world, e2, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 2);
|
||||
test_int(p->y, 3);
|
||||
|
||||
p = ecs_get(world, e3, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 4);
|
||||
test_int(p->y, 6);
|
||||
|
||||
p = ecs_get(world, e4, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 4);
|
||||
test_int(p->y, 6);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void SystemCascade_custom_relation_cascade_depth_2(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_ENTITY(world, Rel, Traversable);
|
||||
|
||||
ECS_ENTITY(world, e1, Position);
|
||||
ECS_ENTITY(world, e2, Position);
|
||||
ECS_ENTITY(world, e3, Position);
|
||||
ECS_ENTITY(world, e4, Position);
|
||||
ECS_ENTITY(world, e5, Position);
|
||||
ECS_ENTITY(world, e6, Position);
|
||||
|
||||
ECS_SYSTEM(world, Iter, EcsOnUpdate, Position, ?Position(cascade(Rel)));
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = Iter,
|
||||
.query.filter.instanced = true
|
||||
});
|
||||
|
||||
ecs_set(world, e1, Position, {1, 2});
|
||||
ecs_set(world, e2, Position, {1, 2});
|
||||
ecs_set(world, e3, Position, {1, 2});
|
||||
ecs_set(world, e4, Position, {1, 2});
|
||||
ecs_set(world, e5, Position, {1, 2});
|
||||
ecs_set(world, e6, Position, {1, 2});
|
||||
|
||||
ecs_add_pair(world, e3, Rel, e1); /* depth 1 */
|
||||
ecs_add_pair(world, e4, Rel, e2); /* depth 1 */
|
||||
ecs_add_pair(world, e5, Rel, e3); /* depth 2 */
|
||||
ecs_add_pair(world, e6, Rel, e4); /* depth 2 */
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(ctx.count, 6);
|
||||
test_int(ctx.invoked, 5);
|
||||
test_int(ctx.system, Iter);
|
||||
test_int(ctx.term_count, 2);
|
||||
test_null(ctx.param);
|
||||
|
||||
test_assert((ctx.e[0] == e1 && ctx.e[1] == e2) || (ctx.e[0] == e2 && ctx.e[1] == e1));
|
||||
test_assert((ctx.e[2] == e3 && ctx.e[3] == e4) || (ctx.e[2] == e4 && ctx.e[3] == e3));
|
||||
test_assert((ctx.e[4] == e5 && ctx.e[5] == e6) || (ctx.e[4] == e6 && ctx.e[5] == e5));
|
||||
|
||||
test_int(ctx.c[0][0], ecs_id(Position));
|
||||
test_int(ctx.s[0][0], 0);
|
||||
|
||||
const Position *p = ecs_get(world, e1, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 2);
|
||||
test_int(p->y, 3);
|
||||
|
||||
p = ecs_get(world, e2, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 2);
|
||||
test_int(p->y, 3);
|
||||
|
||||
p = ecs_get(world, e3, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 4);
|
||||
test_int(p->y, 6);
|
||||
|
||||
p = ecs_get(world, e4, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 4);
|
||||
test_int(p->y, 6);
|
||||
|
||||
p = ecs_get(world, e5, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 6);
|
||||
test_int(p->y, 9);
|
||||
|
||||
p = ecs_get(world, e6, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 6);
|
||||
test_int(p->y, 9);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void SystemCascade_custom_relation_add_after_match(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_ENTITY(world, Rel, Traversable);
|
||||
|
||||
ECS_ENTITY(world, e1, Position);
|
||||
ECS_ENTITY(world, e2, Position);
|
||||
ECS_ENTITY(world, e3, Position);
|
||||
ECS_ENTITY(world, e4, Position);
|
||||
|
||||
ECS_SYSTEM(world, AddParent, EcsOnUpdate, Position, ?Position(cascade(Rel)));
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = AddParent,
|
||||
.query.filter.instanced = true
|
||||
});
|
||||
|
||||
ecs_entity_t parent = ecs_new(world, 0);
|
||||
ecs_set(world, e1, Position, {1, 2});
|
||||
ecs_set(world, e2, Position, {1, 2});
|
||||
ecs_set(world, e3, Position, {1, 2});
|
||||
ecs_set(world, e4, Position, {1, 2});
|
||||
|
||||
ecs_add_pair(world, e3, Rel, parent); /* depth 1 */
|
||||
ecs_add_pair(world, e4, Rel, parent); /* depth 1 */
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
/* Before adding Position to parent, it wasn't being considered for the
|
||||
* column(parent|cascade), so tables could have been ordered randomly. Make sure
|
||||
* that queries can handle changes to depth after all tables are matched */
|
||||
ecs_set(world, parent, Position, {1, 2});
|
||||
|
||||
ecs_os_zeromem(&ctx);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(ctx.count, 5);
|
||||
test_int(ctx.invoked, 3);
|
||||
test_int(ctx.system, AddParent);
|
||||
test_int(ctx.term_count, 2);
|
||||
test_null(ctx.param);
|
||||
|
||||
test_assert(ctx.e[0] == e1 || ctx.e[1] == e1 || ctx.e[2] == e1);
|
||||
test_assert(ctx.e[0] == e2 || ctx.e[1] == e2 || ctx.e[2] == e2);
|
||||
test_assert(ctx.e[0] == parent || ctx.e[1] == parent || ctx.e[2] == parent);
|
||||
test_assert(ctx.e[3] == e3 || ctx.e[4] == e3);
|
||||
test_assert(ctx.e[3] == e4 || ctx.e[4] == e4);
|
||||
|
||||
test_int(ctx.c[0][0], ecs_id(Position));
|
||||
test_int(ctx.s[0][0], 0);
|
||||
|
||||
const Position *p = ecs_get(world, e1, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 1);
|
||||
test_int(p->y, 2);
|
||||
|
||||
p = ecs_get(world, e2, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 1);
|
||||
test_int(p->y, 2);
|
||||
|
||||
p = ecs_get(world, e3, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 2);
|
||||
test_int(p->y, 4);
|
||||
|
||||
p = ecs_get(world, e4, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 2);
|
||||
test_int(p->y, 4);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void SystemCascade_custom_relation_adopt_after_match(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_ENTITY(world, Rel, Traversable);
|
||||
|
||||
ECS_ENTITY(world, e1, Position);
|
||||
ECS_ENTITY(world, e2, Position);
|
||||
ECS_ENTITY(world, e3, Position);
|
||||
ECS_ENTITY(world, e4, Position);
|
||||
|
||||
ECS_SYSTEM(world, AddParent, EcsOnUpdate, Position, ?Position(cascade(Rel)));
|
||||
ecs_system_init(world, &(ecs_system_desc_t){
|
||||
.entity = AddParent,
|
||||
.query.filter.instanced = true
|
||||
});
|
||||
|
||||
ecs_entity_t parent = ecs_set(world, 0, Position, {1, 2});
|
||||
ecs_set(world, e1, Position, {1, 2});
|
||||
ecs_set(world, e2, Position, {1, 2});
|
||||
ecs_set(world, e3, Position, {1, 2});
|
||||
ecs_set(world, e4, Position, {1, 2});
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
ecs_add_pair(world, e3, Rel, parent);
|
||||
ecs_add_pair(world, e4, Rel, parent);
|
||||
|
||||
ecs_os_zeromem(&ctx);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(ctx.count, 5);
|
||||
test_int(ctx.invoked, 3);
|
||||
test_int(ctx.system, AddParent);
|
||||
test_int(ctx.term_count, 2);
|
||||
test_null(ctx.param);
|
||||
|
||||
test_int(ctx.e[0], e1);
|
||||
test_int(ctx.e[1], e2);
|
||||
test_int(ctx.e[2], parent);
|
||||
test_int(ctx.e[3], e3);
|
||||
test_int(ctx.e[4], e4);
|
||||
test_int(ctx.c[0][0], ecs_id(Position));
|
||||
test_int(ctx.s[0][0], 0);
|
||||
|
||||
const Position *p = ecs_get(world, e1, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 1);
|
||||
test_int(p->y, 2);
|
||||
|
||||
p = ecs_get(world, e2, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 1);
|
||||
test_int(p->y, 2);
|
||||
|
||||
p = ecs_get(world, e3, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 2);
|
||||
test_int(p->y, 4);
|
||||
|
||||
p = ecs_get(world, e4, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 2);
|
||||
test_int(p->y, 4);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
156
engine/libs/flecs/test/addons/src/SystemManual.c
Normal file
156
engine/libs/flecs/test/addons/src/SystemManual.c
Normal file
@@ -0,0 +1,156 @@
|
||||
#include <addons.h>
|
||||
|
||||
void SystemManual_setup(void) {
|
||||
ecs_log_set_level(-3);
|
||||
}
|
||||
|
||||
static
|
||||
void Iter(ecs_iter_t *it) {
|
||||
Position *p = ecs_field(it, Position, 1);
|
||||
Velocity *v = NULL;
|
||||
Mass *m = NULL;
|
||||
|
||||
if (it->field_count >= 2) {
|
||||
v = ecs_field(it, Velocity, 2);
|
||||
}
|
||||
|
||||
if (it->field_count >= 3) {
|
||||
m = ecs_field(it, Mass, 3);
|
||||
}
|
||||
|
||||
probe_iter(it);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
p[i].x = 10;
|
||||
p[i].y = 20;
|
||||
|
||||
if (v) {
|
||||
v[i].x = 30;
|
||||
v[i].y = 40;
|
||||
}
|
||||
|
||||
if (m) {
|
||||
m[i] = 50;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SystemManual_1_type_1_component(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_SYSTEM(world, Iter, 0, Position);
|
||||
|
||||
ECS_ENTITY(world, e1, Position);
|
||||
ECS_ENTITY(world, e2, Position);
|
||||
ECS_ENTITY(world, e3, Position);
|
||||
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_run(world, Iter, 1, NULL);
|
||||
|
||||
test_int(ctx.count, 3);
|
||||
test_int(ctx.invoked, 1);
|
||||
test_int(ctx.system, Iter);
|
||||
test_int(ctx.term_count, 1);
|
||||
test_null(ctx.param);
|
||||
|
||||
test_int(ctx.e[0], e1);
|
||||
test_int(ctx.e[1], e2);
|
||||
test_int(ctx.e[2], e3);
|
||||
test_int(ctx.c[0][0], ecs_id(Position));
|
||||
test_int(ctx.s[0][0], 0);
|
||||
|
||||
const Position *p = ecs_get(world, e1, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
p = ecs_get(world, e2, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
p = ecs_get(world, e3, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static int normal_count;
|
||||
|
||||
static
|
||||
void NormalSystem(ecs_iter_t *it) {
|
||||
normal_count ++;
|
||||
}
|
||||
|
||||
static
|
||||
void AddVelocity(ecs_iter_t *it) {
|
||||
ecs_id_t ecs_id(Velocity) = ecs_field_id(it, 2);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
ecs_add(it->world, it->entities[i], Velocity);
|
||||
}
|
||||
}
|
||||
|
||||
void SystemManual_no_automerge(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ECS_SYSTEM(world, AddVelocity, 0, Position, Velocity());
|
||||
|
||||
ECS_ENTITY(world, e1, Position);
|
||||
|
||||
ecs_set_automerge(world, false);
|
||||
|
||||
ecs_readonly_begin(world);
|
||||
ecs_world_t *stage = ecs_get_stage(world, 0);
|
||||
|
||||
ecs_run(stage, AddVelocity, 1, NULL);
|
||||
|
||||
test_assert(!ecs_has(stage, e1, Velocity));
|
||||
|
||||
ecs_readonly_end(world);
|
||||
|
||||
test_assert(!ecs_has(world, e1, Velocity));
|
||||
|
||||
ecs_merge(world);
|
||||
|
||||
test_assert(ecs_has(world, e1, Velocity));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static int dummy_ran = 0;
|
||||
|
||||
void DummySystem(ecs_iter_t *it) {
|
||||
ecs_entity_t Tag = ecs_field_id(it, 1);
|
||||
ecs_add_id(it->world, Tag, Tag);
|
||||
dummy_ran ++;
|
||||
}
|
||||
|
||||
void SystemManual_dont_run_w_unmatching_entity_query(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, Tag);
|
||||
|
||||
ECS_SYSTEM(world, DummySystem, 0, !Tag($));
|
||||
|
||||
ecs_run(world, DummySystem, 0, NULL);
|
||||
test_int(dummy_ran, 1);
|
||||
|
||||
dummy_ran = 0;
|
||||
|
||||
ecs_run(world, DummySystem, 0, NULL);
|
||||
test_int(dummy_ran, 0);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
1778
engine/libs/flecs/test/addons/src/SystemMisc.c
Normal file
1778
engine/libs/flecs/test/addons/src/SystemMisc.c
Normal file
File diff suppressed because it is too large
Load Diff
1927
engine/libs/flecs/test/addons/src/SystemPeriodic.c
Normal file
1927
engine/libs/flecs/test/addons/src/SystemPeriodic.c
Normal file
File diff suppressed because it is too large
Load Diff
107
engine/libs/flecs/test/addons/src/System_w_Empty.c
Normal file
107
engine/libs/flecs/test/addons/src/System_w_Empty.c
Normal file
@@ -0,0 +1,107 @@
|
||||
#include <addons.h>
|
||||
|
||||
static
|
||||
void Iter(ecs_iter_t *it) {
|
||||
Position *p = ecs_field(it, Position, 1);
|
||||
|
||||
probe_iter(it);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
p[i].x = 10;
|
||||
p[i].y = 20;
|
||||
}
|
||||
}
|
||||
|
||||
void System_w_Empty_2_column_1_from_id(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ECS_SYSTEM(world, Iter, EcsOnUpdate, Position, Velocity());
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_entity_t e = ecs_new(world, Position);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(ctx.count, 1);
|
||||
test_int(ctx.invoked, 1);
|
||||
test_int(ctx.system, Iter);
|
||||
test_int(ctx.term_count, 2);
|
||||
test_null(ctx.param);
|
||||
|
||||
test_int(ctx.e[0], e);
|
||||
test_int(ctx.c[0][0], ecs_id(Position));
|
||||
test_int(ctx.s[0][0], 0);
|
||||
test_int(ctx.c[0][1], ecs_id(Velocity));
|
||||
test_int(ctx.s[0][1], 0);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void System_w_Empty_3_column_2_from_id(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
ECS_COMPONENT(world, Rotation);
|
||||
|
||||
ECS_SYSTEM(world, Iter, EcsOnUpdate, Position, Velocity(), Rotation());
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_entity_t e = ecs_new(world, Position);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(ctx.count, 1);
|
||||
test_int(ctx.invoked, 1);
|
||||
test_int(ctx.system, Iter);
|
||||
test_int(ctx.term_count, 3);
|
||||
test_null(ctx.param);
|
||||
|
||||
test_int(ctx.e[0], e);
|
||||
test_int(ctx.c[0][0], ecs_id(Position));
|
||||
test_int(ctx.s[0][0], 0);
|
||||
test_int(ctx.c[0][1], ecs_id(Velocity));
|
||||
test_int(ctx.s[0][1], 0);
|
||||
test_int(ctx.c[0][2], ecs_id(Rotation));
|
||||
test_int(ctx.s[0][2], 0);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static
|
||||
void CheckColumnType(ecs_iter_t *it) {
|
||||
ecs_id_t ecs_id(Position) = ecs_field_id(it, 2);
|
||||
|
||||
test_assert(ecs_id(Position) == ecs_field_id(it, 1));
|
||||
|
||||
probe_iter(it);
|
||||
}
|
||||
|
||||
void System_w_Empty_column_type(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
ECS_COMPONENT(world, Rotation);
|
||||
|
||||
ECS_SYSTEM(world, CheckColumnType, EcsOnUpdate, Position, Position());
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_new(world, Position);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(ctx.count, 1);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
141
engine/libs/flecs/test/addons/src/System_w_FromEntity.c
Normal file
141
engine/libs/flecs/test/addons/src/System_w_FromEntity.c
Normal file
@@ -0,0 +1,141 @@
|
||||
#include <addons.h>
|
||||
|
||||
static
|
||||
void Iter(ecs_iter_t *it) {
|
||||
Mass *m_ptr = ecs_field(it, Mass, 1);
|
||||
|
||||
Position *p = NULL;
|
||||
Velocity *v = NULL;
|
||||
|
||||
if (it->field_count >= 2) {
|
||||
p = ecs_field(it, Position, 2);
|
||||
}
|
||||
|
||||
if (it->field_count >= 3) {
|
||||
v = ecs_field(it, Velocity, 3);
|
||||
}
|
||||
|
||||
test_assert(!m_ptr || !ecs_field_is_self(it, 1));
|
||||
|
||||
probe_iter(it);
|
||||
|
||||
Mass m = 1;
|
||||
if (m_ptr) {
|
||||
m = *m_ptr;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
p[i].x = 10 * m;
|
||||
p[i].y = 20 * m;
|
||||
|
||||
if (v) {
|
||||
v[i].x = 30 * m;
|
||||
v[i].y = 40 * m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void System_w_FromEntity_2_column_1_from_entity(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Mass);
|
||||
|
||||
ECS_ENTITY(world, e1, Mass);
|
||||
ECS_ENTITY(world, e2, Position);
|
||||
|
||||
ECS_SYSTEM(world, Iter, EcsOnUpdate, Mass(e1), Position);
|
||||
|
||||
ecs_set(world, e1, Mass, {5});
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(ctx.count, 1);
|
||||
test_int(ctx.invoked, 1);
|
||||
test_int(ctx.system, Iter);
|
||||
test_int(ctx.term_count, 2);
|
||||
test_null(ctx.param);
|
||||
|
||||
test_int(ctx.e[0], e2);
|
||||
test_int(ctx.c[0][0], ecs_id(Mass));
|
||||
test_int(ctx.s[0][0], e1);
|
||||
test_int(ctx.c[0][1], ecs_id(Position));
|
||||
test_int(ctx.s[0][1], 0);
|
||||
|
||||
const Position *p = ecs_get(world, e2, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 50);
|
||||
test_int(p->y, 100);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static bool dummy_invoked = 0;
|
||||
static ecs_entity_t dummy_component = 0;
|
||||
static ecs_entity_t dummy_source = 0;
|
||||
|
||||
static
|
||||
void dummy_reset(void) {
|
||||
dummy_invoked = false;
|
||||
dummy_component = 0;
|
||||
dummy_source = 0;
|
||||
}
|
||||
|
||||
static
|
||||
void Dummy(ecs_iter_t *it) {
|
||||
dummy_invoked = 1;
|
||||
dummy_component = ecs_field_id(it, 1);
|
||||
dummy_source = ecs_field_src(it, 1);
|
||||
}
|
||||
|
||||
void System_w_FromEntity_task_from_entity(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_ENTITY(world, e1, Position);
|
||||
|
||||
ECS_SYSTEM(world, Dummy, EcsOnUpdate, Position(e1));
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_bool(dummy_invoked, true);
|
||||
test_assert(dummy_component == ecs_id(Position));
|
||||
test_assert(dummy_source == e1);
|
||||
|
||||
dummy_reset();
|
||||
ecs_remove(world, e1, Position);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
test_bool(dummy_invoked, false);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void System_w_FromEntity_task_not_from_entity(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_ENTITY(world, e1, Position);
|
||||
|
||||
ECS_SYSTEM(world, Dummy, EcsOnUpdate, !Position(e1));
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_bool(dummy_invoked, false);
|
||||
|
||||
ecs_remove(world, e1, Position);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_bool(dummy_invoked, true);
|
||||
test_assert(dummy_component == ecs_id(Position));
|
||||
test_assert(dummy_source == e1);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
1294
engine/libs/flecs/test/addons/src/System_w_FromParent.c
Normal file
1294
engine/libs/flecs/test/addons/src/System_w_FromParent.c
Normal file
File diff suppressed because it is too large
Load Diff
196
engine/libs/flecs/test/addons/src/System_w_FromSystem.c
Normal file
196
engine/libs/flecs/test/addons/src/System_w_FromSystem.c
Normal file
@@ -0,0 +1,196 @@
|
||||
#include <addons.h>
|
||||
|
||||
void InitVelocity(ecs_iter_t *it) {
|
||||
Velocity *v = ecs_field(it, Velocity, 1);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
v[i].x = 10;
|
||||
v[i].y = 20;
|
||||
}
|
||||
}
|
||||
|
||||
void InitMass(ecs_iter_t *it) {
|
||||
Mass *m = ecs_field(it, Mass, 1);
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
m[i] = 3;
|
||||
}
|
||||
}
|
||||
|
||||
void Iter(ecs_iter_t *it) {
|
||||
Position *p = ecs_field(it, Position, 1);
|
||||
|
||||
Velocity *v = NULL;
|
||||
Mass *m = NULL;
|
||||
|
||||
if (it->field_count >= 2) {
|
||||
v = ecs_field(it, Velocity, 2);
|
||||
test_assert(!ecs_field_is_self(it, 2));
|
||||
}
|
||||
|
||||
if (it->field_count >= 3) {
|
||||
m = ecs_field(it, Mass, 3);
|
||||
test_assert(!m || !ecs_field_is_self(it, 3));
|
||||
}
|
||||
|
||||
probe_iter(it);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
p[i].x += v->x;
|
||||
p[i].y += v->y;
|
||||
|
||||
if (m) {
|
||||
p[i].x += *m;
|
||||
p[i].y += *m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void System_w_FromSystem_2_column_1_from_system(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
|
||||
ECS_OBSERVER(world, InitVelocity, EcsOnAdd, Velocity);
|
||||
ECS_SYSTEM(world, Iter, EcsOnUpdate, Position, Velocity(Iter));
|
||||
|
||||
test_assert( ecs_has(world, Iter, Velocity));
|
||||
const Velocity *v = ecs_get(world, Iter, Velocity);
|
||||
test_assert(v != NULL);
|
||||
test_int(v->x, 10);
|
||||
test_int(v->y, 20);
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_entity_t e = ecs_set(world, 0, Position, {0, 0});
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(ctx.count, 1);
|
||||
test_int(ctx.invoked, 1);
|
||||
test_int(ctx.system, Iter);
|
||||
test_int(ctx.term_count, 2);
|
||||
test_null(ctx.param);
|
||||
|
||||
test_int(ctx.e[0], e);
|
||||
test_int(ctx.c[0][0], ecs_id(Position));
|
||||
test_int(ctx.s[0][0], 0);
|
||||
test_int(ctx.c[0][1], ecs_id(Velocity));
|
||||
test_int(ctx.s[0][1], Iter);
|
||||
|
||||
const Position *p = ecs_get(world, e, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 10);
|
||||
test_int(p->y, 20);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(p->x, 20);
|
||||
test_int(p->y, 40);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void System_w_FromSystem_3_column_2_from_system(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_COMPONENT(world, Velocity);
|
||||
ECS_COMPONENT(world, Mass);
|
||||
|
||||
ECS_OBSERVER(world, InitVelocity, EcsOnAdd, Velocity);
|
||||
ECS_OBSERVER(world, InitMass, EcsOnAdd, Mass);
|
||||
ECS_SYSTEM(world, Iter, EcsOnUpdate, Position, Velocity(Iter), Mass(Iter));
|
||||
|
||||
test_assert( ecs_has(world, Iter, Velocity));
|
||||
const Velocity *v = ecs_get(world, Iter, Velocity);
|
||||
test_assert(v != NULL);
|
||||
test_int(v->x, 10);
|
||||
test_int(v->y, 20);
|
||||
|
||||
test_assert( ecs_has(world, Iter, Mass));
|
||||
const Mass *m = ecs_get(world, Iter, Mass);
|
||||
test_assert(m != NULL);
|
||||
test_int(*m, 3);
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_entity_t e = ecs_set(world, 0, Position, {0, 0});
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(ctx.count, 1);
|
||||
test_int(ctx.invoked, 1);
|
||||
test_int(ctx.system, Iter);
|
||||
test_int(ctx.term_count, 3);
|
||||
test_null(ctx.param);
|
||||
|
||||
test_int(ctx.e[0], e);
|
||||
test_int(ctx.c[0][0], ecs_id(Position));
|
||||
test_int(ctx.s[0][0], 0);
|
||||
test_int(ctx.c[0][1], ecs_id(Velocity));
|
||||
test_int(ctx.s[0][1], Iter);
|
||||
test_int(ctx.c[0][2], ecs_id(Mass));
|
||||
test_int(ctx.s[0][2], Iter);
|
||||
|
||||
const Position *p = ecs_get(world, e, Position);
|
||||
test_assert(p != NULL);
|
||||
test_int(p->x, 13);
|
||||
test_int(p->y, 23);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(p->x, 26);
|
||||
test_int(p->y, 46);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Iter_reactive(ecs_iter_t *it) {
|
||||
Position *p = ecs_field(it, Position, 1);
|
||||
|
||||
Velocity *v = it->param;
|
||||
Mass *m = NULL;
|
||||
|
||||
if (it->field_count >= 2) {
|
||||
v = ecs_field(it, Velocity, 2);
|
||||
test_assert(!ecs_field_is_self(it, 2));
|
||||
}
|
||||
|
||||
probe_iter(it);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
p[i].x = v->x;
|
||||
p[i].y = v->y;
|
||||
|
||||
if (m) {
|
||||
p[i].x = *m;
|
||||
p[i].y = *m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Dummy_1(ecs_iter_t *it) { }
|
||||
void Dummy_2(ecs_iter_t *it) { }
|
||||
|
||||
void System_w_FromSystem_auto_add_tag(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, Foo);
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_SYSTEM(world, Dummy_1, EcsOnUpdate, Position, Foo(Dummy_1));
|
||||
ECS_SYSTEM(world, Dummy_2, 0, Position, Foo(Dummy_2));
|
||||
|
||||
test_assert( ecs_has_id(world, Dummy_1, Foo));
|
||||
test_assert( ecs_has_id(world, Dummy_2, Foo));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
150
engine/libs/flecs/test/addons/src/Tasks.c
Normal file
150
engine/libs/flecs/test/addons/src/Tasks.c
Normal file
@@ -0,0 +1,150 @@
|
||||
#include <addons.h>
|
||||
|
||||
void Task(ecs_iter_t *it) {
|
||||
probe_iter(it);
|
||||
}
|
||||
|
||||
void Tasks_no_components(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_SYSTEM(world, Task, EcsOnUpdate, 0);
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(ctx.count, 0);
|
||||
test_int(ctx.invoked, 1);
|
||||
test_int(ctx.term_count, 0);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Tasks_one_tag(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_TAG(world, Foo);
|
||||
|
||||
ECS_SYSTEM(world, Task, EcsOnUpdate, Foo(Task));
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(ctx.count, 0);
|
||||
test_int(ctx.invoked, 1);
|
||||
test_int(ctx.term_count, 1);
|
||||
test_int(ctx.c[0][0], Foo);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Tasks_from_system(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_SYSTEM(world, Task, EcsOnUpdate, Position(Task));
|
||||
|
||||
Probe ctx = {0};
|
||||
ecs_set_ctx(world, &ctx, NULL);
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(ctx.count, 0);
|
||||
test_int(ctx.invoked, 1);
|
||||
test_int(ctx.term_count, 1);
|
||||
test_int(ctx.c[0][0], ecs_id(Position));
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static int phase_counter = 0;
|
||||
|
||||
static
|
||||
void OnLoadTask(ecs_iter_t *it) {
|
||||
test_assert(it->entities == NULL);
|
||||
test_int(it->count, 0);
|
||||
test_int(phase_counter, 0);
|
||||
phase_counter ++;
|
||||
}
|
||||
|
||||
static
|
||||
void PostLoadTask(ecs_iter_t *it) {
|
||||
test_assert(it->entities == NULL);
|
||||
test_int(it->count, 0);
|
||||
test_int(phase_counter, 1);
|
||||
phase_counter ++;
|
||||
}
|
||||
|
||||
static
|
||||
void PreUpdateTask(ecs_iter_t *it) {
|
||||
test_assert(it->entities == NULL);
|
||||
test_int(it->count, 0);
|
||||
test_int(phase_counter, 2);
|
||||
phase_counter ++;
|
||||
}
|
||||
|
||||
static
|
||||
void OnUpdateTask(ecs_iter_t *it) {
|
||||
test_assert(it->entities == NULL);
|
||||
test_int(it->count, 0);
|
||||
test_int(phase_counter, 3);
|
||||
phase_counter ++;
|
||||
}
|
||||
|
||||
static
|
||||
void OnValidateTask(ecs_iter_t *it) {
|
||||
test_assert(it->entities == NULL);
|
||||
test_int(it->count, 0);
|
||||
test_int(phase_counter, 4);
|
||||
phase_counter ++;
|
||||
}
|
||||
|
||||
static
|
||||
void PostUpdateTask(ecs_iter_t *it) {
|
||||
test_assert(it->entities == NULL);
|
||||
test_int(it->count, 0);
|
||||
test_int(phase_counter, 5);
|
||||
phase_counter ++;
|
||||
}
|
||||
|
||||
static
|
||||
void PreStoreTask(ecs_iter_t *it) {
|
||||
test_assert(it->entities == NULL);
|
||||
test_int(it->count, 0);
|
||||
test_int(phase_counter, 6);
|
||||
phase_counter ++;
|
||||
}
|
||||
|
||||
static
|
||||
void OnStoreTask(ecs_iter_t *it) {
|
||||
test_assert(it->entities == NULL);
|
||||
test_int(it->count, 0);
|
||||
test_int(phase_counter, 7);
|
||||
phase_counter ++;
|
||||
}
|
||||
|
||||
void Tasks_tasks_in_phases(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_SYSTEM(world, OnLoadTask, EcsOnLoad, Position());
|
||||
ECS_SYSTEM(world, PostLoadTask, EcsPostLoad, Position());
|
||||
ECS_SYSTEM(world, PreUpdateTask, EcsPreUpdate, Position());
|
||||
ECS_SYSTEM(world, OnUpdateTask, EcsOnUpdate, Position());
|
||||
ECS_SYSTEM(world, OnValidateTask, EcsOnValidate, Position());
|
||||
ECS_SYSTEM(world, PostUpdateTask, EcsPostUpdate, Position());
|
||||
ECS_SYSTEM(world, PreStoreTask, EcsPreStore, Position());
|
||||
ECS_SYSTEM(world, OnStoreTask, EcsOnStore, Position());
|
||||
|
||||
ecs_progress(world, 1);
|
||||
|
||||
test_int(phase_counter, 8);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
758
engine/libs/flecs/test/addons/src/Timer.c
Normal file
758
engine/libs/flecs/test/addons/src/Timer.c
Normal file
@@ -0,0 +1,758 @@
|
||||
#include <addons.h>
|
||||
|
||||
static bool system_a_invoked;
|
||||
static bool system_b_invoked;
|
||||
static bool system_c_invoked;
|
||||
|
||||
static
|
||||
void SystemA(ecs_iter_t *it) {
|
||||
test_int(it->delta_time, 1.0);
|
||||
test_int(it->delta_system_time, 3.0);
|
||||
system_a_invoked = true;
|
||||
}
|
||||
|
||||
static
|
||||
void SystemB(ecs_iter_t *it) {
|
||||
test_int(it->delta_time, 1.0);
|
||||
test_int(it->delta_system_time, 3.0);
|
||||
system_b_invoked = true;
|
||||
}
|
||||
|
||||
void Timer_timeout(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_SYSTEM(world, SystemA, EcsOnUpdate, Position);
|
||||
|
||||
ecs_new(world, Position);
|
||||
|
||||
ecs_entity_t timer = ecs_set_timeout(world, SystemA, 3.0);
|
||||
test_assert(timer != 0);
|
||||
test_assert(timer == SystemA);
|
||||
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, true);
|
||||
|
||||
system_a_invoked = false;
|
||||
|
||||
/* Make sure this was a one-shot timer */
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Timer_interval(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_SYSTEM(world, SystemA, EcsOnUpdate, Position);
|
||||
|
||||
ecs_new(world, Position);
|
||||
|
||||
ecs_entity_t timer = ecs_set_interval(world, SystemA, 3.0);
|
||||
test_assert(timer != 0);
|
||||
test_assert(timer == SystemA);
|
||||
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, true);
|
||||
|
||||
system_a_invoked = false;
|
||||
|
||||
/* Make sure this was not a one-shot timer */
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, true);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Timer_shared_timeout(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_SYSTEM(world, SystemA, EcsOnUpdate, Position);
|
||||
ECS_SYSTEM(world, SystemB, EcsOnUpdate, Position);
|
||||
|
||||
ecs_new(world, Position);
|
||||
|
||||
ecs_entity_t timer = ecs_set_timeout(world, 0, 3.0);
|
||||
test_assert(timer != 0);
|
||||
|
||||
ecs_set_tick_source(world, SystemA, timer);
|
||||
ecs_set_tick_source(world, SystemB, timer);
|
||||
|
||||
test_bool(system_a_invoked, false);
|
||||
test_bool(system_b_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
test_bool(system_b_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
test_bool(system_b_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, true);
|
||||
test_bool(system_b_invoked, true);
|
||||
|
||||
system_a_invoked = false;
|
||||
system_b_invoked = false;
|
||||
|
||||
/* Make sure this was a one-shot timer */
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
test_bool(system_b_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
test_bool(system_b_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
test_bool(system_b_invoked, false);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Timer_shared_interval(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_SYSTEM(world, SystemA, EcsOnUpdate, Position);
|
||||
ECS_SYSTEM(world, SystemB, EcsOnUpdate, Position);
|
||||
|
||||
ecs_new(world, Position);
|
||||
|
||||
ecs_entity_t timer = ecs_set_interval(world, 0, 3.0);
|
||||
test_assert(timer != 0);
|
||||
|
||||
ecs_set_tick_source(world, SystemA, timer);
|
||||
ecs_set_tick_source(world, SystemB, timer);
|
||||
|
||||
test_bool(system_a_invoked, false);
|
||||
test_bool(system_b_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
test_bool(system_b_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
test_bool(system_b_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, true);
|
||||
test_bool(system_b_invoked, true);
|
||||
|
||||
system_a_invoked = false;
|
||||
system_b_invoked = false;
|
||||
|
||||
/* Make sure this was a one-shot timer */
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
test_bool(system_b_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
test_bool(system_b_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, true);
|
||||
test_bool(system_b_invoked, true);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Timer_start_stop_one_shot(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_SYSTEM(world, SystemA, EcsOnUpdate, Position);
|
||||
|
||||
ecs_new(world, Position);
|
||||
|
||||
ecs_entity_t timer = ecs_set_timeout(world, SystemA, 3.0);
|
||||
test_assert(timer != 0);
|
||||
test_assert(timer == SystemA);
|
||||
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
|
||||
/* Stop timer */
|
||||
ecs_stop_timer(world, timer);
|
||||
|
||||
/* Timer is stopped, should not trigger system */
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
|
||||
/* Start timer, this should reset timer */
|
||||
ecs_start_timer(world, timer);
|
||||
|
||||
/* Make sure this was a one-shot timer */
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
|
||||
/* System should have been triggered */
|
||||
test_bool(system_a_invoked, true);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Timer_start_stop_interval(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_SYSTEM(world, SystemA, EcsOnUpdate, Position);
|
||||
|
||||
ecs_new(world, Position);
|
||||
|
||||
ecs_entity_t timer = ecs_set_interval(world, SystemA, 3.0);
|
||||
test_assert(timer != 0);
|
||||
test_assert(timer == SystemA);
|
||||
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
|
||||
/* Stop timer */
|
||||
ecs_stop_timer(world, timer);
|
||||
|
||||
/* Timer is stopped, should not trigger system */
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
|
||||
/* Start timer, this should reset timer */
|
||||
ecs_start_timer(world, timer);
|
||||
|
||||
/* Make sure this was a one-shot timer */
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
|
||||
/* System should have been triggered */
|
||||
test_bool(system_a_invoked, true);
|
||||
|
||||
system_a_invoked = false;
|
||||
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
|
||||
/* Ensure that timer still triggers repeatedly */
|
||||
test_bool(system_a_invoked, true);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Timer_rate_filter(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_SYSTEM(world, SystemA, EcsOnUpdate, Position);
|
||||
|
||||
ecs_new(world, Position);
|
||||
|
||||
ecs_entity_t filter = ecs_set_rate(world, SystemA, 3, 0);
|
||||
test_assert(filter != 0);
|
||||
test_assert(filter == SystemA);
|
||||
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, true);
|
||||
|
||||
system_a_invoked = false;
|
||||
|
||||
/* Make sure this was a one-shot timer */
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, false);
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_a_invoked, true);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
static
|
||||
void SystemC(ecs_iter_t *it) {
|
||||
test_int(it->delta_time, 1.0);
|
||||
test_int(it->delta_system_time, 6.0);
|
||||
system_c_invoked = true;
|
||||
}
|
||||
|
||||
void Timer_rate_filter_w_rate_filter_src(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_SYSTEM(world, SystemC, EcsOnUpdate, Position);
|
||||
|
||||
ecs_new(world, Position);
|
||||
|
||||
ecs_entity_t filter_a = ecs_set_rate(world, 0, 2, 0);
|
||||
test_assert(filter_a != 0);
|
||||
|
||||
ecs_entity_t filter_b = ecs_set_rate(world, SystemC, 3, filter_a);
|
||||
test_assert(filter_b != 0);
|
||||
test_assert(filter_b == SystemC);
|
||||
|
||||
test_bool(system_c_invoked, false);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 5; i ++) {
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_c_invoked, false);
|
||||
}
|
||||
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_c_invoked, true);
|
||||
|
||||
system_c_invoked = false;
|
||||
|
||||
/* Make sure rate filter triggers repeatedly */
|
||||
for (i = 0; i < 5; i ++) {
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_c_invoked, false);
|
||||
}
|
||||
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_c_invoked, true);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Timer_rate_filter_w_timer_src(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
ECS_SYSTEM(world, SystemC, EcsOnUpdate, Position);
|
||||
ECS_ENTITY(world, E1, Position);
|
||||
|
||||
ecs_entity_t timer = ecs_set_interval(world, 0, 2.0);
|
||||
test_assert(timer != 0);
|
||||
|
||||
ecs_entity_t filter = ecs_set_rate(world, SystemC, 3, timer);
|
||||
test_assert(filter != 0);
|
||||
test_assert(filter == SystemC);
|
||||
|
||||
test_bool(system_c_invoked, false);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 5; i ++) {
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_c_invoked, false);
|
||||
}
|
||||
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_c_invoked, true);
|
||||
|
||||
system_c_invoked = false;
|
||||
|
||||
/* Make sure rate filter triggers repeatedly */
|
||||
for (i = 0; i < 5; i ++) {
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_c_invoked, false);
|
||||
}
|
||||
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_c_invoked, true);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Timer_rate_filter_with_empty_src(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ECS_COMPONENT(world, Position);
|
||||
|
||||
ECS_SYSTEM(world, SystemC, EcsOnUpdate, Position);
|
||||
|
||||
ecs_new(world, Position);
|
||||
|
||||
// Not actually a tick source
|
||||
ecs_entity_t filter_a = ecs_new_id(world);
|
||||
test_assert(filter_a != 0);
|
||||
|
||||
ecs_entity_t filter_b = ecs_set_rate(world, SystemC, 6, filter_a);
|
||||
test_assert(filter_b != 0);
|
||||
test_assert(filter_b == SystemC);
|
||||
|
||||
test_bool(system_c_invoked, false);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 5; i ++) {
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_c_invoked, false);
|
||||
}
|
||||
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_c_invoked, true);
|
||||
|
||||
system_c_invoked = false;
|
||||
|
||||
/* Make sure rate filter triggers repeatedly */
|
||||
for (i = 0; i < 5; i ++) {
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_c_invoked, false);
|
||||
}
|
||||
|
||||
ecs_progress(world, 1.0);
|
||||
test_bool(system_c_invoked, true);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Timer_one_shot_timer_entity(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_entity_t timer = ecs_set_timeout(world, 0, 1.0);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 3; i ++) {
|
||||
ecs_progress(world, 0.3);
|
||||
const EcsTickSource *src = ecs_get(world, timer, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, false);
|
||||
}
|
||||
|
||||
ecs_progress(world, 0.3);
|
||||
const EcsTickSource *src = ecs_get(world, timer, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, true);
|
||||
|
||||
/* Ensure timer doesn't tick again */
|
||||
for (i = 0; i < 12; i ++) {
|
||||
ecs_progress(world, 0.3);
|
||||
test_bool(src->tick, false);
|
||||
}
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Timer_interval_timer_entity(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_entity_t timer = ecs_set_interval(world, 0, 1.0);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 3; i ++) {
|
||||
ecs_progress(world, 0.3);
|
||||
const EcsTickSource *src = ecs_get(world, timer, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, false);
|
||||
}
|
||||
|
||||
ecs_progress(world, 0.3);
|
||||
const EcsTickSource *src = ecs_get(world, timer, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, true);
|
||||
|
||||
for (i = 0; i < 2; i ++) {
|
||||
ecs_progress(world, 0.3);
|
||||
test_bool(src->tick, false);
|
||||
}
|
||||
|
||||
/* Timer should tick again */
|
||||
ecs_progress(world, 0.3);
|
||||
test_bool(src->tick, true);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Timer_rate_entity(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
/* Specify 0 for source. This applies the rate to the frame ticks */
|
||||
ecs_entity_t rate = ecs_set_rate(world, 0, 4, 0);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 3; i ++) {
|
||||
ecs_progress(world, 0);
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, false);
|
||||
}
|
||||
|
||||
ecs_progress(world, 0);
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, true);
|
||||
|
||||
for (i = 0; i < 3; i ++) {
|
||||
ecs_progress(world, 0);
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, false);
|
||||
}
|
||||
|
||||
/* Filter should tick again */
|
||||
ecs_progress(world, 0);
|
||||
test_bool(src->tick, true);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Timer_nested_rate_entity(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
/* Nested rate filter */
|
||||
ecs_entity_t parent = ecs_set_rate(world, 0, 2, 0);
|
||||
ecs_entity_t rate = ecs_set_rate(world, 0, 2, parent);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 3; i ++) {
|
||||
ecs_progress(world, 0);
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, false);
|
||||
}
|
||||
|
||||
ecs_progress(world, 0);
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, true);
|
||||
|
||||
for (i = 0; i < 3; i ++) {
|
||||
ecs_progress(world, 0);
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, false);
|
||||
}
|
||||
|
||||
/* Filter should tick again */
|
||||
ecs_progress(world, 0);
|
||||
test_bool(src->tick, true);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Timer_nested_rate_entity_empty_src(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
/* Rate filter with source that is not a tick source */
|
||||
ecs_entity_t parent = ecs_new(world, 0);
|
||||
ecs_entity_t rate = ecs_set_rate(world, 0, 4, parent);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 3; i ++) {
|
||||
ecs_progress(world, 0);
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, false);
|
||||
}
|
||||
|
||||
ecs_progress(world, 0);
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, true);
|
||||
|
||||
for (i = 0; i < 3; i ++) {
|
||||
ecs_progress(world, 0);
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, false);
|
||||
}
|
||||
|
||||
/* Filter should tick again */
|
||||
ecs_progress(world, 0);
|
||||
test_bool(src->tick, true);
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Timer_naked_tick_entity(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_entity_t tick = ecs_set(world, 0, EcsTickSource, {0});
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 10; i ++) {
|
||||
ecs_progress(world, 0);
|
||||
const EcsTickSource *src = ecs_get(world, tick, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
|
||||
/* Tick should always be true, no filter is applied */
|
||||
test_bool(src->tick, true);
|
||||
}
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Timer_stop_timer_w_rate(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_entity_t timer = ecs_set_interval(world, 0, 1.0);
|
||||
ecs_entity_t rate = ecs_set_rate(world, 0, 3.0, timer);
|
||||
|
||||
for (int i = 0; i < 5; i ++) {
|
||||
ecs_progress(world, 0.5);
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, false);
|
||||
}
|
||||
|
||||
ecs_progress(world, 0.5);
|
||||
|
||||
{
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, true);
|
||||
}
|
||||
|
||||
ecs_stop_timer(world, timer);
|
||||
|
||||
for (int i = 0; i < 5; i ++) {
|
||||
ecs_progress(world, 0.5);
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, false);
|
||||
}
|
||||
|
||||
ecs_progress(world, 0.5);
|
||||
|
||||
{
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, false);
|
||||
}
|
||||
|
||||
ecs_start_timer(world, timer);
|
||||
|
||||
for (int i = 0; i < 5; i ++) {
|
||||
ecs_progress(world, 0.5);
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, false);
|
||||
}
|
||||
|
||||
ecs_progress(world, 0.5);
|
||||
|
||||
{
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, true);
|
||||
}
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Timer_stop_timer_w_rate_same_src(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_entity_t timer = ecs_set_interval(world, 0, 1.0);
|
||||
ecs_entity_t rate = ecs_set_rate(world, timer, 3.0, timer);
|
||||
test_assert(rate == timer);
|
||||
|
||||
for (int i = 0; i < 5; i ++) {
|
||||
ecs_progress(world, 0.5);
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, false);
|
||||
}
|
||||
|
||||
ecs_progress(world, 0.5);
|
||||
|
||||
{
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, true);
|
||||
}
|
||||
|
||||
ecs_stop_timer(world, timer);
|
||||
|
||||
for (int i = 0; i < 5; i ++) {
|
||||
ecs_progress(world, 0.5);
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, false);
|
||||
}
|
||||
|
||||
ecs_progress(world, 0.5);
|
||||
|
||||
{
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, false);
|
||||
}
|
||||
|
||||
ecs_start_timer(world, timer);
|
||||
|
||||
for (int i = 0; i < 5; i ++) {
|
||||
ecs_progress(world, 0.5);
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, false);
|
||||
}
|
||||
|
||||
ecs_progress(world, 0.5);
|
||||
|
||||
{
|
||||
const EcsTickSource *src = ecs_get(world, rate, EcsTickSource);
|
||||
test_assert(src != NULL);
|
||||
test_bool(src->tick, true);
|
||||
}
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
|
||||
void Timer_randomize_timers(void) {
|
||||
ecs_world_t *world = ecs_init();
|
||||
|
||||
ecs_entity_t timer_a = ecs_set_interval(world, 0, 1.0);
|
||||
{
|
||||
const EcsTimer *t = ecs_get(world, timer_a, EcsTimer);
|
||||
test_assert(t != NULL);
|
||||
test_assert(t->time == 0);
|
||||
}
|
||||
|
||||
ecs_randomize_timers(world);
|
||||
|
||||
{
|
||||
const EcsTimer *t = ecs_get(world, timer_a, EcsTimer);
|
||||
test_assert(t != NULL);
|
||||
test_assert(t->time != 0);
|
||||
}
|
||||
|
||||
ecs_entity_t timer_b = ecs_set_interval(world, 0, 1.0);
|
||||
{
|
||||
const EcsTimer *t = ecs_get(world, timer_b, EcsTimer);
|
||||
test_assert(t != NULL);
|
||||
test_assert(t->time != 0);
|
||||
}
|
||||
|
||||
ecs_fini(world);
|
||||
}
|
||||
7999
engine/libs/flecs/test/addons/src/main.c
Normal file
7999
engine/libs/flecs/test/addons/src/main.c
Normal file
File diff suppressed because it is too large
Load Diff
319
engine/libs/flecs/test/addons/src/util.c
Normal file
319
engine/libs/flecs/test/addons/src/util.c
Normal file
@@ -0,0 +1,319 @@
|
||||
#include <addons.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void probe_system_w_ctx(
|
||||
ecs_iter_t *it,
|
||||
Probe *ctx)
|
||||
{
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->param = it->param;
|
||||
ctx->system = it->system;
|
||||
ctx->event = it->event;
|
||||
ctx->event_id = it->event_id;
|
||||
ctx->offset = 0;
|
||||
ctx->term_count = it->field_count;
|
||||
ctx->term_index = it->term_index;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < ctx->term_count; i ++) {
|
||||
ctx->c[ctx->invoked][i] = it->ids[i];
|
||||
ctx->s[ctx->invoked][i] = ecs_field_src(it, i + 1);
|
||||
|
||||
ecs_id_t e = ecs_field_id(it, i + 1);
|
||||
test_assert(e != 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < it->count; i ++) {
|
||||
if (i + ctx->count < 256) {
|
||||
ctx->e[i + ctx->count] = it->entities[i];
|
||||
} else {
|
||||
/* can't store more than that, tests shouldn't rely on
|
||||
* getting back more than 256 results */
|
||||
}
|
||||
}
|
||||
ctx->count += it->count;
|
||||
|
||||
ctx->invoked ++;
|
||||
}
|
||||
|
||||
void probe_iter(
|
||||
ecs_iter_t *it)
|
||||
{
|
||||
Probe *ctx = ecs_get_ctx(it->world);
|
||||
if (!ctx) {
|
||||
ctx = it->ctx;
|
||||
}
|
||||
probe_system_w_ctx(it, ctx);
|
||||
}
|
||||
|
||||
void probe_has_entity(Probe *probe, ecs_entity_t e) {
|
||||
int i;
|
||||
for (i = 0; i < probe->count; i ++) {
|
||||
if (probe->e[i] == e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
test_assert(i != probe->count);
|
||||
}
|
||||
|
||||
void install_test_abort(void) {
|
||||
ecs_os_set_api_defaults();
|
||||
ecs_os_api_t os_api = ecs_os_api;
|
||||
os_api.abort_ = test_abort;
|
||||
ecs_os_set_api(&os_api);
|
||||
ecs_log_set_level(-5);
|
||||
}
|
||||
|
||||
const ecs_entity_t* bulk_new_w_type(
|
||||
ecs_world_t *world, ecs_entity_t type_ent, int32_t count)
|
||||
{
|
||||
const ecs_type_t *type = ecs_get_type(world, type_ent);
|
||||
test_assert(type != NULL);
|
||||
|
||||
ecs_id_t *ids = type->array;
|
||||
int i = 0;
|
||||
while ((ecs_id_get_flags(world, ids[i]) & EcsIdDontInherit)) {
|
||||
i ++;
|
||||
}
|
||||
const ecs_entity_t *result = ecs_bulk_new_w_id(world, ids[i], count);
|
||||
for (; i < type->count; i ++) {
|
||||
for (int e = 0; e < count; e ++) {
|
||||
if (ecs_id_get_flags(world, ids[i]) & EcsIdDontInherit) {
|
||||
continue;
|
||||
}
|
||||
ecs_add_id(world, result[e], ids[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t find_entity(
|
||||
ecs_world_t *world,
|
||||
test_iter_result_t *expect,
|
||||
ecs_entity_t e)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ITER_MAX_ENTITIES; i ++) {
|
||||
if (expect->entities[i] == e) {
|
||||
while (expect->matched[i]) {
|
||||
i ++;
|
||||
if (!if_test_assert(e == expect->entities[i])) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (expect->entity_names[i]) {
|
||||
if (!if_test_str(ecs_get_name(world, e), expect->entity_names[i])) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ITER_MAX_ENTITIES; i ++) {
|
||||
if (!expect->entity_names[i]) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!strcmp(ecs_get_name(world, e), expect->entity_names[i])) {
|
||||
while (expect->matched[i]) {
|
||||
i ++;
|
||||
|
||||
// If this fails, the entity is encountered more times than
|
||||
// expected.
|
||||
if (!if_test_str(ecs_get_name(world, e),
|
||||
expect->entity_names[i]))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool test_iter(
|
||||
ecs_iter_t *it,
|
||||
ecs_iter_next_action_t next,
|
||||
test_iter_result_t *expect)
|
||||
{
|
||||
int32_t entity_index = -1;
|
||||
|
||||
while (next(it)) {
|
||||
int i;
|
||||
|
||||
for (i = 0; (i < it->count) || (i < 1); i ++) {
|
||||
ecs_entity_t e = 0;
|
||||
int t;
|
||||
|
||||
if (it->count) {
|
||||
e = it->entities[i];
|
||||
|
||||
entity_index = find_entity(it->world, expect, e);
|
||||
|
||||
// Matched unexpected entity
|
||||
test_assert(entity_index != -1);
|
||||
|
||||
expect->matched[entity_index] = true;
|
||||
|
||||
// Test data
|
||||
for (t = 0; t < it->field_count; t++) {
|
||||
size_t size = ecs_field_size(it, t + 1);
|
||||
if (!size) {
|
||||
continue;
|
||||
}
|
||||
|
||||
void *expect_ptr = expect->term_columns[t];
|
||||
if (!expect_ptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
expect_ptr = ECS_OFFSET(expect_ptr, size * entity_index);
|
||||
|
||||
void *component_ptr = ecs_field_w_size(it, size, t + 1);
|
||||
if (!if_test_assert(component_ptr != NULL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
component_ptr = ECS_OFFSET(component_ptr, size * i);
|
||||
if (!if_test_assert(memcpy(component_ptr, expect_ptr, size))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
entity_index ++;
|
||||
}
|
||||
|
||||
|
||||
// Test ids
|
||||
ecs_id_t *ids = expect->term_ids[entity_index];
|
||||
if (!ids[0]) {
|
||||
ids = expect->term_ids[0];
|
||||
}
|
||||
|
||||
for (t = 0; t < it->field_count; t++) {
|
||||
if (!ids[t]) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!if_test_assert(ecs_field_id(it, t + 1) == ids[t])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!if_test_assert(ids[t] == 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Test ids by expr
|
||||
char **ids_expect = expect->term_ids_expr[entity_index];
|
||||
if (!ids_expect) {
|
||||
ids_expect = expect->term_ids_expr[0];
|
||||
}
|
||||
|
||||
for (t = 0; t < it->field_count; t++) {
|
||||
if (!ids_expect[t]) {
|
||||
break;
|
||||
}
|
||||
|
||||
char *id_found = ecs_id_str(it->world, ecs_field_id(it, t + 1));
|
||||
if (!if_test_str(id_found, ids_expect[t])) {
|
||||
printf(" - term %d\n", t);
|
||||
if (e) {
|
||||
printf(" - matched entity %u (%s, [%s])\n",
|
||||
(uint32_t)e,
|
||||
ecs_get_name(it->world, e),
|
||||
ecs_type_str(it->world, ecs_get_type(it->world, e)));
|
||||
|
||||
if (expect->entities[i]) {
|
||||
printf(" - expected entity %u (%s)\n",
|
||||
(uint32_t)expect->entities[i],
|
||||
ecs_get_name(it->world, expect->entities[i]));
|
||||
} else if (expect->entity_names[i]) {
|
||||
printf(" - expected entity %s\n",
|
||||
expect->entity_names[i]);
|
||||
}
|
||||
}
|
||||
|
||||
printf(" - @ result index %d\n", entity_index);
|
||||
return false;
|
||||
}
|
||||
ecs_os_free(id_found);
|
||||
}
|
||||
|
||||
if (!if_test_assert(ids_expect[t] == NULL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Test variables
|
||||
int v;
|
||||
for (v = 0; v < ITER_MAX_VARIABLES; v++) {
|
||||
int32_t id = expect->variables[v].id;
|
||||
if (!id) {
|
||||
break;
|
||||
}
|
||||
|
||||
ecs_entity_t e = expect->variables[v].entities[entity_index];
|
||||
if (!e) {
|
||||
e = expect->variables[v].entities[0];
|
||||
}
|
||||
if (e) {
|
||||
ecs_entity_t var = ecs_iter_get_var(it, id);
|
||||
if (!if_test_assert(e == var)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const char *name = expect->variables[v].entity_names[entity_index];
|
||||
if (!name) {
|
||||
name = expect->variables[v].entity_names[0];
|
||||
}
|
||||
if (name) {
|
||||
ecs_entity_t var = ecs_iter_get_var(it, id);
|
||||
if (!if_test_str(name, ecs_get_name(it->world, var))) {
|
||||
printf(" - variable id %d\n", id);
|
||||
printf(" - index %d\n", entity_index);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* If a variable id is set, either an entity or entity name must
|
||||
* be set. */
|
||||
if (!if_test_assert(e || name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expect->table_count_actual ++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ITER_MAX_ENTITIES; i ++) {
|
||||
if (expect->entities[i] || expect->entity_names[i]) {
|
||||
if (!if_test_assert(expect->matched[i])) {
|
||||
printf(" - entity %u (%s) at index %d not matched\n",
|
||||
(uint32_t)expect->entities[i], expect->entity_names[i], i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (expect->table_count_expect) {
|
||||
if (!if_test_assert(expect->table_count_actual == expect->table_count_expect)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user