Properly link flecs library

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

View File

@@ -0,0 +1,367 @@
#ifndef CPP_API_H
#define CPP_API_H
/* This generated file contains includes for project dependencies */
#include <cpp_api/bake_config.h>
#include <string>
#include <vector>
struct Position {
float x;
float y;
};
struct Velocity {
float x;
float y;
};
struct Mass {
float value;
};
struct Rotation {
float value;
};
struct Tag { };
struct Self {
flecs::entity_view value;
};
enum Number {
One = 1,
Two = 2,
Three = 3
};
class Pod {
public:
struct Child { };
Pod() {
ctor_invoked ++;
value = 10;
}
Pod(int v) {
ctor_invoked ++;
value = v;
}
~Pod() {
dtor_invoked ++;
}
Pod(const Pod& obj) {
copy_ctor_invoked ++;
this->value = obj.value;
}
Pod(Pod&& obj) {
move_ctor_invoked ++;
this->value = obj.value;
}
Pod& operator=(const Pod& obj) {
copy_invoked ++;
this->value = obj.value;
return *this;
}
Pod& operator=(Pod&& obj) {
move_invoked ++;
this->value = obj.value;
return *this;
}
int value;
static int ctor_invoked;
static int dtor_invoked;
static int copy_invoked;
static int move_invoked;
static int copy_ctor_invoked;
static int move_ctor_invoked;
};
struct TagA { };
struct TagB { };
struct TagC { };
struct TagD { };
struct TagE { };
struct TagF { };
struct TagG { };
struct TagH { };
struct TagI { };
struct TagJ { };
struct TagK { };
struct TagL { };
struct TagM { };
struct TagN { };
struct TagO { };
struct TagP { };
struct TagQ { };
struct TagR { };
struct TagS { };
struct TagT { };
template <typename T>
struct Template {
T x;
T y;
};
struct NoDefaultCtor {
NoDefaultCtor(int x) : x_(x) { }
NoDefaultCtor(const NoDefaultCtor& obj) = default;
NoDefaultCtor(NoDefaultCtor&& obj) = default;
NoDefaultCtor& operator=(const NoDefaultCtor& obj) = default;
NoDefaultCtor& operator=(NoDefaultCtor&& obj) = default;
~NoDefaultCtor() { }
int x_;
};
struct DefaultInit {
DefaultInit() : x_(99) { test_assert(y_ == 99); }
DefaultInit(int x) : x_(x) { test_assert(y_ == 99); }
DefaultInit(const DefaultInit& obj) = default;
DefaultInit(DefaultInit&& obj) = default;
DefaultInit& operator=(const DefaultInit& obj) = default;
DefaultInit& operator=(DefaultInit&& obj) = default;
~DefaultInit() { }
int x_;
int y_ = 99;
};
struct NoCopy {
NoCopy() : x_(99) { }
NoCopy(int x) : x_(x) { }
NoCopy(const NoCopy& obj) = delete;
NoCopy(NoCopy&& obj) = default;
NoCopy& operator=(const NoCopy& obj) = delete;
NoCopy& operator=(NoCopy&& obj) = default;
~NoCopy() { }
int x_;
};
struct NoMove {
NoMove() : x_(99) { }
NoMove(int x) : x_(x) { }
NoMove(const NoMove& obj) = default;
NoMove(NoMove&& obj) = delete;
NoMove& operator=(const NoMove& obj) = default;
NoMove& operator=(NoMove&& obj) = delete;
~NoMove() { }
int x_;
};
struct NoCopyCtor {
NoCopyCtor() : x_(99) { }
NoCopyCtor(int x) : x_(x) { }
NoCopyCtor(const NoCopyCtor& obj) = delete;
NoCopyCtor(NoCopyCtor&& obj) = default;
NoCopyCtor& operator=(const NoCopyCtor& obj) = default;
NoCopyCtor& operator=(NoCopyCtor&& obj) = default;
~NoCopyCtor() { }
int x_;
};
struct NoCopyAssign {
NoCopyAssign() : x_(99) { }
NoCopyAssign(int x) : x_(x) { }
NoCopyAssign(const NoCopyAssign& obj) = default;
NoCopyAssign(NoCopyAssign&& obj) = default;
NoCopyAssign& operator=(const NoCopyAssign& obj) = delete;
NoCopyAssign& operator=(NoCopyAssign&& obj) = default;
~NoCopyAssign() { }
int x_;
};
struct NoMoveCtor {
NoMoveCtor() : x_(99) { }
NoMoveCtor(int x) : x_(x) { }
NoMoveCtor(const NoMoveCtor& obj) = default;
NoMoveCtor(NoMoveCtor&& obj) = delete;
NoMoveCtor& operator=(const NoMoveCtor& obj) = default;
NoMoveCtor& operator=(NoMoveCtor&& obj) = default;
~NoMoveCtor() { }
int x_;
};
struct NoMoveAssign {
NoMoveAssign() : x_(99) { }
NoMoveAssign(int x) : x_(x) { }
NoMoveAssign(const NoMoveAssign& obj) = default;
NoMoveAssign(NoMoveAssign&& obj) = default;
NoMoveAssign& operator=(const NoMoveAssign& obj) = default;
NoMoveAssign& operator=(NoMoveAssign&& obj) = delete;
~NoMoveAssign() { }
int x_;
};
struct NoDtor {
NoDtor() : x_(99) { }
NoDtor(int x) : x_(x) { }
NoDtor(const NoDtor& obj) = default;
NoDtor(NoDtor&& obj) = default;
NoDtor& operator=(const NoDtor& obj) = delete;
NoDtor& operator=(NoDtor&& obj) = default;
~NoDtor() = delete;
int x_;
};
struct FlecsCtor {
FlecsCtor(flecs::world&, flecs::entity e) : x_(89), e_(e) { }
FlecsCtor(const FlecsCtor& obj) = delete;
FlecsCtor(FlecsCtor&& obj) = default;
FlecsCtor& operator=(const FlecsCtor& obj) = default;
FlecsCtor& operator=(FlecsCtor&& obj) = default;
~FlecsCtor() { }
int x_;
flecs::entity e_;
};
struct FlecsCtorDefaultCtor {
FlecsCtorDefaultCtor() : x_(99) { }
FlecsCtorDefaultCtor(flecs::world&, flecs::entity e) : x_(89), e_(e) { }
FlecsCtorDefaultCtor(const FlecsCtorDefaultCtor& obj) = delete;
FlecsCtorDefaultCtor(FlecsCtorDefaultCtor&& obj) = default;
FlecsCtorDefaultCtor& operator=(const FlecsCtorDefaultCtor& obj) = default;
FlecsCtorDefaultCtor& operator=(FlecsCtorDefaultCtor&& obj) = default;
~FlecsCtorDefaultCtor() { }
int x_;
flecs::entity e_;
};
struct DefaultCtorValueCtor {
DefaultCtorValueCtor() : x_(99) { }
DefaultCtorValueCtor(int x) : x_(x) { }
DefaultCtorValueCtor(const DefaultCtorValueCtor& obj) = delete;
DefaultCtorValueCtor(DefaultCtorValueCtor&& obj) = default;
DefaultCtorValueCtor& operator=(const DefaultCtorValueCtor& obj) = default;
DefaultCtorValueCtor& operator=(DefaultCtorValueCtor&& obj) = default;
~DefaultCtorValueCtor() { }
int x_;
};
struct FlecsCtorValueCtor {
FlecsCtorValueCtor(int x) : x_(x) { }
FlecsCtorValueCtor(flecs::world&, flecs::entity e) : x_(89), e_(e) { }
FlecsCtorValueCtor(const FlecsCtorValueCtor& obj) = delete;
FlecsCtorValueCtor(FlecsCtorValueCtor&& obj) = default;
FlecsCtorValueCtor& operator=(const FlecsCtorValueCtor& obj) = default;
FlecsCtorValueCtor& operator=(FlecsCtorValueCtor&& obj) = default;
~FlecsCtorValueCtor() { }
int x_;
flecs::entity e_;
};
class CountNoDefaultCtor {
public:
CountNoDefaultCtor(int v) {
ctor_invoked ++;
value = v;
}
~CountNoDefaultCtor() {
dtor_invoked ++;
}
CountNoDefaultCtor(const CountNoDefaultCtor& obj) {
copy_ctor_invoked ++;
this->value = obj.value;
}
CountNoDefaultCtor(CountNoDefaultCtor&& obj) {
move_ctor_invoked ++;
this->value = obj.value;
}
CountNoDefaultCtor& operator=(const CountNoDefaultCtor& obj) {
copy_invoked ++;
this->value = obj.value;
return *this;
}
CountNoDefaultCtor& operator=(CountNoDefaultCtor&& obj) {
move_invoked ++;
this->value = obj.value;
return *this;
}
static void reset() {
ctor_invoked = 0;
dtor_invoked = 0;
copy_invoked = 0;
move_invoked = 0;
copy_ctor_invoked = 0;
move_ctor_invoked = 0;
}
int value;
static int ctor_invoked;
static int dtor_invoked;
static int copy_invoked;
static int move_invoked;
static int copy_ctor_invoked;
static int move_ctor_invoked;
};
struct Struct_w_string {
std::string value;
};
struct Struct_w_vector {
std::vector<int> value;
};
void install_test_abort(void);
#endif

View 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 CPP_API_BAKE_CONFIG_H
#define CPP_API_BAKE_CONFIG_H
/* Headers of public dependencies */
#include <flecs.h>
#include <bake_test.h>
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,59 @@
#include <cpp_api.h>
void Doc_set_brief(void) {
flecs::world ecs;
auto e = ecs.entity("Foo");
e.set_doc_brief("A brief description");
test_assert(e.has<flecs::doc::Description>(flecs::doc::Brief));
test_str(e.doc_brief(), "A brief description");
}
void Doc_set_name(void) {
flecs::world ecs;
auto e = ecs.entity("Foo");
e.set_doc_name("A name");
test_assert(e.has<flecs::doc::Description>(flecs::Name));
test_str(e.doc_name(), "A name");
}
void Doc_set_link(void) {
flecs::world ecs;
auto e = ecs.entity("Foo");
e.set_doc_link("A link");
test_assert(e.has<flecs::doc::Description>(flecs::doc::Link));
test_str(e.doc_link(), "A link");
}
void Doc_set_color(void) {
flecs::world ecs;
auto e = ecs.entity("Foo");
e.set_doc_color("A color");
test_assert(e.has<flecs::doc::Description>(flecs::doc::Color));
test_str(e.doc_color(), "A color");
}
void Doc_get_name_no_doc_name(void) {
flecs::world ecs;
auto e = ecs.entity("Foo");
test_assert(!e.has<flecs::doc::Description>(flecs::Name));
test_str(e.doc_name(), "Foo");
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,941 @@
#include <cpp_api.h>
enum StandardEnum {
Red, Green, Blue
};
enum AnotherEnum {
Standing, Walking, Running
};
enum SparseEnum {
Black = 1, White = 3, Grey = 5
};
enum class EnumClass {
Grass, Sand, Stone
};
enum PrefixEnum {
PrefixEnumFoo, PrefixEnumBar
};
enum ConstantsWithNum {
Num1,
Num2,
Num3,
};
enum class EnumIncorrectType : uint8_t {
A, B
};
enum EnumWithLargeConstant {
X, Y, Z = 1000
};
enum class EnumClassWithLargeConstant {
X, Y, Z = 1000
};
/* Optional, but improves compile time */
FLECS_ENUM_LAST(StandardEnum, Blue)
FLECS_ENUM_LAST(SparseEnum, Grey)
FLECS_ENUM_LAST(EnumClass, EnumClass::Stone)
void Enum_standard_enum_reflection(void) {
flecs::world ecs;
auto enum_type = flecs::enum_type<StandardEnum>(ecs);
auto e = enum_type.entity();
test_assert(e != 0);
test_assert(e == ecs.component<StandardEnum>());
test_str(e.path().c_str(), "::StandardEnum");
test_int(enum_type.first(), Red);
test_int(enum_type.last(), Blue);
auto e_red = enum_type.entity(Red);
auto e_green = enum_type.entity(Green);
auto e_blue = enum_type.entity(Blue);
test_assert(e_red != 0);
test_str(e_red.path().c_str(), "::StandardEnum::Red");
test_bool(enum_type.is_valid(Red), true);
test_assert(e_red.get<StandardEnum>() != nullptr);
test_assert(e_red.get<StandardEnum>()[0] == Red);
test_assert(e_green != 0);
test_str(e_green.path().c_str(), "::StandardEnum::Green");
test_bool(enum_type.is_valid(Green), true);
test_assert(e_green.get<StandardEnum>() != nullptr);
test_assert(e_green.get<StandardEnum>()[0] == Green);
test_assert(e_blue != 0);
test_str(e_blue.path().c_str(), "::StandardEnum::Blue");
test_bool(enum_type.is_valid(Blue), true);
test_assert(e_blue.get<StandardEnum>() != nullptr);
test_assert(e_blue.get<StandardEnum>()[0] == Blue);
test_bool(enum_type.is_valid(Blue + 1), false);
}
void Enum_sparse_enum_reflection(void) {
flecs::world ecs;
auto enum_type = flecs::enum_type<SparseEnum>(ecs);
auto e = enum_type.entity();
test_assert(e != 0);
test_assert(e == ecs.component<SparseEnum>());
test_str(e.path().c_str(), "::SparseEnum");
test_int(enum_type.first(), Black);
test_int(enum_type.last(), Grey);
auto e_black = enum_type.entity(Black);
auto e_white = enum_type.entity(White);
auto e_grey = enum_type.entity(Grey);
test_assert(e_black != 0);
test_str(e_black.path().c_str(), "::SparseEnum::Black");
test_bool(enum_type.is_valid(Black), true);
test_assert(e_black.get<SparseEnum>() != nullptr);
test_assert(e_black.get<SparseEnum>()[0] == Black);
test_assert(e_white != 0);
test_str(e_white.path().c_str(), "::SparseEnum::White");
test_bool(enum_type.is_valid(White), true);
test_assert(e_white.get<SparseEnum>() != nullptr);
test_assert(e_white.get<SparseEnum>()[0] == White);
test_assert(e_grey != 0);
test_str(e_grey.path().c_str(), "::SparseEnum::Grey");
test_bool(enum_type.is_valid(Grey), true);
test_assert(e_grey.get<SparseEnum>() != nullptr);
test_assert(e_grey.get<SparseEnum>()[0] == Grey);
test_bool(enum_type.is_valid(0), false);
test_bool(enum_type.is_valid(2), false);
test_bool(enum_type.is_valid(4), false);
test_bool(enum_type.is_valid(6), false);
}
void Enum_enum_class_reflection(void) {
flecs::world ecs;
auto enum_type = flecs::enum_type<EnumClass>(ecs);
auto e = enum_type.entity();
test_assert(e != 0);
test_assert(e == ecs.component<EnumClass>());
test_str(e.path().c_str(), "::EnumClass");
test_int(enum_type.first(), (int)EnumClass::Grass);
test_int(enum_type.last(), (int)EnumClass::Stone);
auto e_grass = enum_type.entity(EnumClass::Grass);
auto e_sand = enum_type.entity(EnumClass::Sand);
auto e_stone = enum_type.entity(EnumClass::Stone);
test_assert(e_grass != 0);
test_str(e_grass.path().c_str(), "::EnumClass::Grass");
test_bool(enum_type.is_valid((int)EnumClass::Grass), true);
test_assert(e_grass.get<EnumClass>() != nullptr);
test_assert(e_grass.get<EnumClass>()[0] == EnumClass::Grass);
test_assert(e_sand != 0);
test_str(e_sand.path().c_str(), "::EnumClass::Sand");
test_bool(enum_type.is_valid((int)EnumClass::Sand), true);
test_assert(e_sand.get<EnumClass>() != nullptr);
test_assert(e_sand.get<EnumClass>()[0] == EnumClass::Sand);
test_assert(e_stone != 0);
test_str(e_stone.path().c_str(), "::EnumClass::Stone");
test_bool(enum_type.is_valid((int)EnumClass::Stone), true);
test_assert(e_stone.get<EnumClass>() != nullptr);
test_assert(e_stone.get<EnumClass>()[0] == EnumClass::Stone);
test_bool(enum_type.is_valid(3), false);
}
void Enum_prefixed_enum_reflection(void) {
flecs::world ecs;
auto enum_type = flecs::enum_type<PrefixEnum>(ecs);
auto e = enum_type.entity();
test_assert(e != 0);
test_assert(e == ecs.component<PrefixEnum>());
test_str(e.path().c_str(), "::PrefixEnum");
test_int(enum_type.first(), PrefixEnum::PrefixEnumFoo);
test_int(enum_type.last(), PrefixEnum::PrefixEnumBar);
auto e_foo = enum_type.entity(PrefixEnum::PrefixEnumFoo);
auto e_bar = enum_type.entity(PrefixEnum::PrefixEnumBar);
test_assert(e_foo != 0);
test_str(e_foo.path().c_str(), "::PrefixEnum::Foo");
test_bool(enum_type.is_valid(PrefixEnum::PrefixEnumFoo), true);
test_assert(e_foo.get<PrefixEnum>() != nullptr);
test_assert(e_foo.get<PrefixEnum>()[0] == PrefixEnum::PrefixEnumFoo);
test_assert(e_bar != 0);
test_str(e_bar.path().c_str(), "::PrefixEnum::Bar");
test_bool(enum_type.is_valid(PrefixEnum::PrefixEnumFoo), true);
test_assert(e_bar.get<PrefixEnum>() != nullptr);
test_assert(e_bar.get<PrefixEnum>()[0] == PrefixEnum::PrefixEnumBar);
test_bool(enum_type.is_valid(PrefixEnum::PrefixEnumBar + 1), false);
}
void Enum_constant_with_num_reflection(void) {
flecs::world ecs;
auto enum_type = flecs::enum_type<ConstantsWithNum>(ecs);
auto e = enum_type.entity();
test_assert(e != 0);
test_assert(e == ecs.component<ConstantsWithNum>());
test_str(e.path().c_str(), "::ConstantsWithNum");
test_int(enum_type.first(), ConstantsWithNum::Num1);
test_int(enum_type.last(), ConstantsWithNum::Num3);
auto num_1 = enum_type.entity(ConstantsWithNum::Num1);
auto num_2 = enum_type.entity(ConstantsWithNum::Num2);
auto num_3 = enum_type.entity(ConstantsWithNum::Num3);
test_assert(num_1 != 0);
test_str(num_1.path().c_str(), "::ConstantsWithNum::Num1");
test_bool(enum_type.is_valid(ConstantsWithNum::Num1), true);
test_assert(num_1.get<ConstantsWithNum>() != nullptr);
test_assert(num_1.get<ConstantsWithNum>()[0] == ConstantsWithNum::Num1);
test_assert(num_2 != 0);
test_str(num_2.path().c_str(), "::ConstantsWithNum::Num2");
test_bool(enum_type.is_valid(ConstantsWithNum::Num1), true);
test_assert(num_2.get<ConstantsWithNum>() != nullptr);
test_assert(num_2.get<ConstantsWithNum>()[0] == ConstantsWithNum::Num2);
test_assert(num_3 != 0);
test_str(num_3.path().c_str(), "::ConstantsWithNum::Num3");
test_bool(enum_type.is_valid(ConstantsWithNum::Num1), true);
test_assert(num_3.get<ConstantsWithNum>() != nullptr);
test_assert(num_3.get<ConstantsWithNum>()[0] == ConstantsWithNum::Num3);
test_bool(enum_type.is_valid(ConstantsWithNum::Num3 + 1), false);
}
void Enum_get_constant_id(void) {
flecs::world ecs;
flecs::entity red = ecs.component<StandardEnum>().lookup("Red");
const StandardEnum *v = red.get<StandardEnum>();
test_assert(v != NULL);
test_assert(v[0] == StandardEnum::Red);
test_assert(red == ecs.id(StandardEnum::Red));
test_str("Red", ecs.entity(StandardEnum::Red).name());
auto e = flecs::enum_type<StandardEnum>(ecs);
test_assert(e.entity(StandardEnum::Red) == red);
}
void Enum_add_enum_constant(void) {
flecs::world ecs;
auto e = ecs.entity().add(StandardEnum::Red);
test_str(e.type().str().c_str(), "(StandardEnum,StandardEnum.Red)");
flecs::id id = e.type().get(0);
test_assert(id.is_pair());
auto r = id.first();
test_assert(r == ecs.component<StandardEnum>());
auto c = r.lookup("Red");
test_assert(r != 0);
test_assert(id == ecs.pair(r, c));
}
void Enum_add_enum_class_constant(void) {
flecs::world ecs;
auto e = ecs.entity().add(EnumClass::Sand);
test_str(e.type().str().c_str(), "(EnumClass,EnumClass.Sand)");
flecs::id id = e.type().get(0);
test_assert(id.is_pair());
auto r = id.first();
test_assert(r == ecs.component<EnumClass>());
auto c = r.lookup("Sand");
test_assert(r != 0);
test_assert(id == ecs.pair(r, c));
}
void Enum_replace_enum_constants(void) {
flecs::world ecs;
auto e = ecs.entity().add(StandardEnum::Red);
test_assert(e.has(StandardEnum::Red));
test_assert(!e.has(StandardEnum::Green));
test_assert(!e.has(StandardEnum::Blue));
e.add(StandardEnum::Green);
test_assert(!e.has(StandardEnum::Red));
test_assert(e.has(StandardEnum::Green));
test_assert(!e.has(StandardEnum::Blue));
e.add(StandardEnum::Blue);
test_assert(!e.has(StandardEnum::Red));
test_assert(!e.has(StandardEnum::Green));
test_assert(e.has(StandardEnum::Blue));
}
void Enum_has_enum(void) {
flecs::world ecs;
auto e = ecs.entity();
test_assert(!e.has<StandardEnum>());
e.add(StandardEnum::Red);
test_assert(e.has<StandardEnum>());
test_assert(e.has(StandardEnum::Red));
test_assert(!e.has(StandardEnum::Green));
test_assert(!e.has(StandardEnum::Blue));
auto r = e.type().get(0).first();
test_assert(r != 0);
test_assert(r == ecs.component<StandardEnum>());
auto c = r.lookup("Red");
test_assert(c != 0);
test_assert(e.has<StandardEnum>(c));
}
void Enum_has_enum_wildcard(void) {
flecs::world ecs;
auto e = ecs.entity();
test_assert(!e.has<StandardEnum>(flecs::Wildcard));
e.add(StandardEnum::Green);
test_assert(e.has<StandardEnum>(flecs::Wildcard));
}
void Enum_get_enum(void) {
flecs::world ecs;
auto e = ecs.entity().add(StandardEnum::Red);
test_assert(e.has(StandardEnum::Red));
const StandardEnum *v = e.get<StandardEnum>();
test_assert(v != NULL);
test_assert(*v == StandardEnum::Red);
e.add(StandardEnum::Green);
test_assert(e.has(StandardEnum::Green));
v = e.get<StandardEnum>();
test_assert(v != NULL);
test_assert(*v == StandardEnum::Green);
}
void Enum_remove_enum(void) {
flecs::world ecs;
auto e = ecs.entity().add(StandardEnum::Green);
test_assert(e.has(StandardEnum::Green));
e.remove<StandardEnum>();
test_assert(!e.has(StandardEnum::Green));
}
void Enum_remove_wildcard(void) {
flecs::world ecs;
auto e = ecs.entity().add(StandardEnum::Green);
test_assert(e.has(StandardEnum::Green));
e.remove<StandardEnum>(flecs::Wildcard);
test_assert(!e.has(StandardEnum::Green));
}
void Enum_enum_as_component(void) {
flecs::world ecs;
auto e = ecs.entity();
e.set<StandardEnum>({StandardEnum::Green});
test_assert(e.has<StandardEnum>());
const StandardEnum *v = e.get<StandardEnum>();
test_assert(v != NULL);
test_assert(v[0] == StandardEnum::Green);
flecs::id id = e.type().get(0);
test_bool(id.is_pair(), false);
test_assert(id == ecs.component<StandardEnum>());
}
void Enum_query_enum_wildcard(void) {
flecs::world ecs;
auto e1 = ecs.entity().add(StandardEnum::Red);
auto e2 = ecs.entity().add(StandardEnum::Green);
auto e3 = ecs.entity().add(StandardEnum::Blue);
auto q = ecs.query_builder()
.term<StandardEnum>(flecs::Wildcard)
.build();
int32_t count = 0;
q.each([&](flecs::iter& it, size_t index) {
if (it.entity(index) == e1) {
test_assert(it.pair(1).second() == ecs.id(StandardEnum::Red));
count ++;
}
if (it.entity(index) == e2) {
test_assert(it.pair(1).second() == ecs.id(StandardEnum::Green));
count ++;
}
if (it.entity(index) == e3) {
test_assert(it.pair(1).second() == ecs.id(StandardEnum::Blue));
count ++;
}
});
test_int(count, 3);
}
void Enum_query_enum_constant(void) {
flecs::world ecs;
ecs.entity().add(StandardEnum::Red);
ecs.entity().add(StandardEnum::Green);
auto e1 = ecs.entity().add(StandardEnum::Blue);
auto q = ecs.query_builder()
.term<StandardEnum>(StandardEnum::Blue)
.build();
int32_t count = 0;
q.each([&](flecs::iter& it, size_t index) {
test_assert(it.entity(index) == e1);
test_assert(it.pair(1).second() == ecs.id(StandardEnum::Blue));
count ++;
});
test_int(count, 1);
}
void Enum_enum_type_from_stage(void) {
flecs::world ecs;
auto stage = ecs.get_stage(0);
ecs.readonly_begin();
auto enum_type = flecs::enum_type<StandardEnum>(stage);
test_assert(enum_type.entity() == ecs.component<StandardEnum>());
ecs.readonly_end();
}
void Enum_add_enum_from_stage(void) {
flecs::world ecs;
auto stage = ecs.get_stage(0);
ecs.readonly_begin();
auto e = stage.entity().add(StandardEnum::Red);
test_assert(!e.has(StandardEnum::Red));
ecs.readonly_end();
test_assert(e.has(StandardEnum::Red));
}
void Enum_enum_w_2_worlds(void) {
{
flecs::world ecs;
auto enum_type = flecs::enum_type<StandardEnum>(ecs);
auto e = enum_type.entity();
test_assert(e != 0);
test_assert(e == ecs.component<StandardEnum>());
test_str(e.path().c_str(), "::StandardEnum");
test_int(enum_type.first(), Red);
test_int(enum_type.last(), Blue);
auto e_red = enum_type.entity(Red);
auto e_green = enum_type.entity(Green);
auto e_blue = enum_type.entity(Blue);
test_assert(e_red != 0);
test_str(e_red.path().c_str(), "::StandardEnum::Red");
test_bool(enum_type.is_valid(Red), true);
test_assert(e_red.get<StandardEnum>() != nullptr);
test_assert(e_red.get<StandardEnum>()[0] == Red);
test_assert(e_green != 0);
test_str(e_green.path().c_str(), "::StandardEnum::Green");
test_bool(enum_type.is_valid(Green), true);
test_assert(e_green.get<StandardEnum>() != nullptr);
test_assert(e_green.get<StandardEnum>()[0] == Green);
test_assert(e_blue != 0);
test_str(e_blue.path().c_str(), "::StandardEnum::Blue");
test_bool(enum_type.is_valid(Blue), true);
test_assert(e_blue.get<StandardEnum>() != nullptr);
test_assert(e_blue.get<StandardEnum>()[0] == Blue);
test_bool(enum_type.is_valid(Blue + 1), false);
}
{
flecs::world ecs;
auto enum_type = flecs::enum_type<StandardEnum>(ecs);
auto e = enum_type.entity();
test_assert(e != 0);
test_assert(e == ecs.component<StandardEnum>());
test_str(e.path().c_str(), "::StandardEnum");
test_int(enum_type.first(), Red);
test_int(enum_type.last(), Blue);
auto e_red = enum_type.entity(Red);
auto e_green = enum_type.entity(Green);
auto e_blue = enum_type.entity(Blue);
test_assert(e_red != 0);
test_str(e_red.path().c_str(), "::StandardEnum::Red");
test_bool(enum_type.is_valid(Red), true);
test_assert(e_red.get<StandardEnum>() != nullptr);
test_assert(e_red.get<StandardEnum>()[0] == Red);
test_assert(e_green != 0);
test_str(e_green.path().c_str(), "::StandardEnum::Green");
test_bool(enum_type.is_valid(Green), true);
test_assert(e_green.get<StandardEnum>() != nullptr);
test_assert(e_green.get<StandardEnum>()[0] == Green);
test_assert(e_blue != 0);
test_str(e_blue.path().c_str(), "::StandardEnum::Blue");
test_bool(enum_type.is_valid(Blue), true);
test_assert(e_blue.get<StandardEnum>() != nullptr);
test_assert(e_blue.get<StandardEnum>()[0] == Blue);
test_bool(enum_type.is_valid(Blue + 1), false);
}
}
struct MyTag { };
void Enum_add_enum_constant_w_tag(void) {
flecs::world ecs;
flecs::entity e1 = ecs.entity()
.add<MyTag>(Red);
flecs::entity e2 = ecs.entity()
.add<MyTag>(Green);
flecs::entity e3 = ecs.entity()
.add<MyTag>(Blue);
test_assert(e1.has<MyTag>(Red));
test_assert(e2.has<MyTag>(Green));
test_assert(e3.has<MyTag>(Blue));
auto enum_type = flecs::enum_type<StandardEnum>(ecs);
auto e_red = enum_type.entity(Red);
auto e_green = enum_type.entity(Green);
auto e_blue = enum_type.entity(Blue);
auto t1 = e1.target<MyTag>();
auto t2 = e2.target<MyTag>();
auto t3 = e3.target<MyTag>();
test_assert(t1 == e_red);
test_assert(t2 == e_green);
test_assert(t3 == e_blue);
}
void Enum_remove_enum_constant_w_tag(void) {
flecs::world ecs;
flecs::entity e1 = ecs.entity()
.add<MyTag>(Red);
flecs::entity e2 = ecs.entity()
.add<MyTag>(Green);
flecs::entity e3 = ecs.entity()
.add<MyTag>(Blue);
test_assert(e1.has<MyTag>(Red));
test_assert(e2.has<MyTag>(Green));
test_assert(e3.has<MyTag>(Blue));
e1.remove<MyTag>(Green);
e1.remove<MyTag>(Blue);
test_assert(e1.has<MyTag>(Red));
e1.remove<MyTag>(Red);
test_assert(!e1.has<MyTag>(Red));
e2.remove<MyTag>(Red);
e2.remove<MyTag>(Blue);
test_assert(e2.has<MyTag>(Green));
e2.remove<MyTag>(Green);
test_assert(!e2.has<MyTag>(Green));
e3.remove<MyTag>(Red);
e3.remove<MyTag>(Green);
test_assert(e3.has<MyTag>(Blue));
e3.remove<MyTag>(Blue);
test_assert(!e3.has<MyTag>(Blue));
}
void Enum_set_enum_constant_w_tag(void) {
flecs::world ecs;
flecs::entity e1 = ecs.entity()
.set<Position>(Red, {1, 2})
.set<Position>(Green, {2, 3})
.set<Position>(Blue, {3, 4});
test_assert(e1.has<Position>(Red));
test_assert(e1.has<Position>(Green));
test_assert(e1.has<Position>(Blue));
const Position *p = e1.get<Position>(Red);
test_assert(p != NULL);
test_int(p->x, 1);
test_int(p->y, 2);
p = e1.get<Position>(Green);
test_assert(p != NULL);
test_int(p->x, 2);
test_int(p->y, 3);
p = e1.get<Position>(Blue);
test_assert(p != NULL);
test_int(p->x, 3);
test_int(p->y, 4);
}
void Enum_enum_w_incorrect_size(void) {
/* Quaratined as test can cause compilation of test suite to fail due to new
* error messages introduced in clang. */
test_quarantine("6 Aug 2023");
// install_test_abort();
// flecs::world ecs;
// test_expect_abort();
// ecs.component<EnumIncorrectType>();
}
void Enum_add_union_enum(void) {
flecs::world ecs;
ecs.component<StandardEnum>().add(flecs::Union);
auto t_color = flecs::enum_type<StandardEnum>(ecs);
auto red = t_color.entity(StandardEnum::Red);
auto blue = t_color.entity(StandardEnum::Blue);
auto e1 = ecs.entity().add(StandardEnum::Red);
auto e2 = ecs.entity().add(StandardEnum::Blue);
test_assert(e1.type() == e2.type());
test_assert(e1.target<StandardEnum>() == red);
test_assert(e2.target<StandardEnum>() == blue);
test_assert(e1.has(StandardEnum::Red));
test_assert(e2.has(StandardEnum::Blue));
}
void Enum_add_2_union_enums(void) {
flecs::world ecs;
ecs.component<StandardEnum>().add(flecs::Union);
ecs.component<AnotherEnum>().add(flecs::Union);
auto e = ecs.entity();
e.add(StandardEnum::Red);
e.add(AnotherEnum::Running);
test_assert(e.has(StandardEnum::Red));
test_assert(e.has(AnotherEnum::Running));
test_assert(e.target<StandardEnum>() != 0);
test_assert(e.target<AnotherEnum>() != 0);
auto t_color = flecs::enum_type<StandardEnum>(ecs);
auto t_AnotherEnum = flecs::enum_type<AnotherEnum>(ecs);
auto red = t_color.entity(StandardEnum::Red);
auto running = t_AnotherEnum.entity(AnotherEnum::Running);
test_assert(e.target<StandardEnum>() == red);
test_assert(e.target<AnotherEnum>() == running);
}
void Enum_add_2_union_enums_reverse(void) {
flecs::world ecs;
ecs.component<StandardEnum>().add(flecs::Union);
ecs.component<AnotherEnum>().add(flecs::Union);
auto e = ecs.entity();
e.add(AnotherEnum::Running);
e.add(StandardEnum::Red);
test_assert(e.has(StandardEnum::Red));
test_assert(e.has(AnotherEnum::Running));
test_assert(e.target<StandardEnum>() != 0);
test_assert(e.target<AnotherEnum>() != 0);
auto t_color = flecs::enum_type<StandardEnum>(ecs);
auto t_AnotherEnum = flecs::enum_type<AnotherEnum>(ecs);
auto red = t_color.entity(StandardEnum::Red);
auto running = t_AnotherEnum.entity(AnotherEnum::Running);
test_assert(e.target<StandardEnum>() == red);
test_assert(e.target<AnotherEnum>() == running);
}
void Enum_constant_from_entity(void) {
flecs::world ecs;
flecs::entity e_red = ecs.to_entity(StandardEnum::Red);
test_assert(e_red != 0);
flecs::entity e_green = ecs.to_entity(StandardEnum::Green);
test_assert(e_green != 0);
flecs::entity e_blue = ecs.to_entity(StandardEnum::Blue);
test_assert(e_blue != 0);
test_assert(e_red.to_constant<StandardEnum>() == StandardEnum::Red);
test_assert(e_green.to_constant<StandardEnum>() == StandardEnum::Green);
test_assert(e_blue.to_constant<StandardEnum>() == StandardEnum::Blue);
}
void Enum_add_if(void) {
flecs::world ecs;
auto e = ecs.entity();
e.add_if(true, StandardEnum::Red);
test_assert(e.has(StandardEnum::Red));
test_assert(e.has<StandardEnum>(ecs.to_entity(StandardEnum::Red)));
e.add_if(false, StandardEnum::Red);
test_assert(!e.has(StandardEnum::Red));
test_assert(!e.has<StandardEnum>(ecs.to_entity(StandardEnum::Red)));
}
void Enum_add_if_other(void) {
flecs::world ecs;
auto e = ecs.entity();
e.add(StandardEnum::Red);
test_assert(e.has(StandardEnum::Red));
test_assert(e.has<StandardEnum>(ecs.to_entity(StandardEnum::Red)));
e.add_if(false, StandardEnum::Blue);
test_assert(!e.has(StandardEnum::Blue));
test_assert(!e.has(StandardEnum::Red));
test_assert(!e.has<StandardEnum>(ecs.to_entity(StandardEnum::Red)));
}
void Enum_query_union_enum(void) {
flecs::world ecs;
enum Color {
Red,
Green,
Blue
};
ecs.component<StandardEnum>().add(flecs::Union);
flecs::entity e1 = ecs.entity().add(StandardEnum::Red);
flecs::entity e2 = ecs.entity().add(StandardEnum::Green);
flecs::entity e3 = ecs.entity().add(StandardEnum::Blue);
auto q = ecs.query_builder()
.term<StandardEnum>().second(flecs::Wildcard)
.build();
q.iter([&](flecs::iter& it) {
flecs::column<flecs::entity_t> colors = it.field<flecs::entity_t>(1);
test_int(it.count(), 3);
test_uint(it.entity(0), e1);
test_uint(it.entity(1), e2);
test_uint(it.entity(2), e3);
test_uint(colors[0], ecs.to_entity(StandardEnum::Red));
test_uint(colors[1], ecs.to_entity(StandardEnum::Green));
test_uint(colors[2], ecs.to_entity(StandardEnum::Blue));
});
}
void Enum_query_union_enum_invalid_query_type(void) {
install_test_abort();
flecs::world ecs;
ecs.component<StandardEnum>().add(flecs::Union);
test_expect_abort();
ecs.query_builder<StandardEnum>()
.term_at(1).second(flecs::Wildcard)
.build();
}
void Enum_component_registered_as_enum(void) {
flecs::world ecs;
auto e = ecs.component<StandardEnum>();
test_assert(e.has<flecs::Enum>());
const flecs::MetaType *mt = e.get<flecs::MetaType>();
test_assert(mt != nullptr);
test_assert(mt->kind == flecs::meta::EnumType);
{
auto c = e.lookup("Red");
test_assert(c != 0);
const StandardEnum *v = c.get<StandardEnum>();
test_assert(v != nullptr);
test_assert(*v == StandardEnum::Red);
const int32_t *vi = c.get_second<int32_t>(flecs::Constant);
test_assert(vi != nullptr);
test_int(*vi, StandardEnum::Red);
}
{
auto c = e.lookup("Green");
test_assert(c != 0);
const StandardEnum *v = c.get<StandardEnum>();
test_assert(v != nullptr);
test_assert(*v == StandardEnum::Green);
const int32_t *vi = c.get_second<int32_t>(flecs::Constant);
test_assert(vi != nullptr);
test_int(*vi, StandardEnum::Green);
}
{
auto c = e.lookup("Blue");
test_assert(c != 0);
const StandardEnum *v = c.get<StandardEnum>();
test_assert(v != nullptr);
test_assert(*v == StandardEnum::Blue);
const int32_t *vi = c.get_second<int32_t>(flecs::Constant);
test_assert(vi != nullptr);
test_int(*vi, StandardEnum::Blue);
}
}
void Enum_mixed_auto_manual_constants(void) {
flecs::world ecs;
auto e = ecs.component<EnumWithLargeConstant>()
.constant("Z", EnumWithLargeConstant::Z);
test_assert(e.has<flecs::Enum>());
const flecs::MetaType *mt = e.get<flecs::MetaType>();
test_assert(mt != nullptr);
test_assert(mt->kind == flecs::meta::EnumType);
{
auto c = e.lookup("X");
test_assert(c != 0);
const EnumWithLargeConstant *v = c.get<EnumWithLargeConstant>();
test_assert(v != nullptr);
test_assert(*v == EnumWithLargeConstant::X);
const int32_t *vi = c.get_second<int32_t>(flecs::Constant);
test_assert(vi != nullptr);
test_int(*vi, EnumWithLargeConstant::X);
}
{
auto c = e.lookup("Y");
test_assert(c != 0);
const EnumWithLargeConstant *v = c.get<EnumWithLargeConstant>();
test_assert(v != nullptr);
test_assert(*v == EnumWithLargeConstant::Y);
const int32_t *vi = c.get_second<int32_t>(flecs::Constant);
test_assert(vi != nullptr);
test_int(*vi, EnumWithLargeConstant::Y);
}
{
auto c = e.lookup("Z");
test_assert(c != 0);
const EnumWithLargeConstant *v = c.get<EnumWithLargeConstant>();
test_assert(v != nullptr);
test_assert(*v == EnumWithLargeConstant::Z);
const int32_t *vi = c.get_second<int32_t>(flecs::Constant);
test_assert(vi != nullptr);
test_int(*vi, EnumWithLargeConstant::Z);
}
}
void Enum_enum_class_mixed_auto_manual_constants(void) {
flecs::world ecs;
auto e = ecs.component<EnumClassWithLargeConstant>()
.constant("Z", EnumClassWithLargeConstant::Z);
test_assert(e.has<flecs::Enum>());
const flecs::MetaType *mt = e.get<flecs::MetaType>();
test_assert(mt != nullptr);
test_assert(mt->kind == flecs::meta::EnumType);
{
auto c = e.lookup("X");
test_assert(c != 0);
const EnumClassWithLargeConstant *v = c.get<EnumClassWithLargeConstant>();
test_assert(v != nullptr);
test_assert(*v == EnumClassWithLargeConstant::X);
const int32_t *vi = c.get_second<int32_t>(flecs::Constant);
test_assert(vi != nullptr);
test_assert(*vi == static_cast<int32_t>(EnumClassWithLargeConstant::X));
}
}
void Enum_enum_child_count(void) {
flecs::world ecs;
flecs::entity e = ecs.component<StandardEnum>();
flecs::filter<> f = ecs.filter_builder()
.with(flecs::ChildOf, e)
.build();
test_assert(f.count() == 3);
}

View File

@@ -0,0 +1,626 @@
#include <cpp_api.h>
struct Evt { };
struct IdA { };
struct IdB { };
void Event_evt_1_id_entity(void) {
flecs::world ecs;
auto evt = ecs.entity();
auto id = ecs.entity();
auto e1 = ecs.entity().add(id);
int32_t count = 0;
ecs.observer()
.event(evt)
.term(id)
.each([&](flecs::entity e) {
test_assert(e == e1);
count ++;
});
ecs.event(evt)
.id(id)
.entity(e1)
.emit();
test_int(count, 1);
}
void Event_evt_2_ids_entity(void) {
flecs::world ecs;
auto evt = ecs.entity();
auto id_a = ecs.entity();
auto id_b = ecs.entity();
auto e1 = ecs.entity().add(id_a).add(id_b);
int32_t count = 0;
ecs.observer()
.event(evt)
.term(id_a)
.each([&](flecs::entity e) {
test_assert(e == e1);
count ++;
});
ecs.observer()
.event(evt)
.term(id_b)
.each([&](flecs::entity e) {
test_assert(e == e1);
count ++;
});
ecs.event(evt)
.id(id_a)
.id(id_b)
.entity(e1)
.emit();
test_int(count, 2);
}
void Event_evt_1_id_table(void) {
flecs::world ecs;
auto evt = ecs.entity();
auto id = ecs.entity();
auto e1 = ecs.entity().add(id);
auto table = e1.table();
int32_t count = 0;
ecs.observer()
.event(evt)
.term(id)
.each([&](flecs::entity e) {
test_assert(e == e1);
count ++;
});
ecs.event(evt)
.id(id)
.table(table)
.emit();
test_int(count, 1);
}
void Event_evt_2_ids_table(void) {
flecs::world ecs;
auto evt = ecs.entity();
auto id_a = ecs.entity();
auto id_b = ecs.entity();
auto e1 = ecs.entity().add(id_a).add(id_b);
auto table = e1.table();
int32_t count = 0;
ecs.observer()
.event(evt)
.term(id_a)
.each([&](flecs::entity e) {
test_assert(e == e1);
count ++;
});
ecs.observer()
.event(evt)
.term(id_b)
.each([&](flecs::entity e) {
test_assert(e == e1);
count ++;
});
ecs.event(evt)
.id(id_a)
.id(id_b)
.table(table)
.emit();
test_int(count, 2);
}
void Event_evt_type(void) {
flecs::world ecs;
auto id = ecs.entity();
auto e1 = ecs.entity().add(id);
int32_t count = 0;
ecs.observer()
.event<Evt>()
.term(id)
.each([&](flecs::entity e) {
test_assert(e == e1);
count ++;
});
ecs.event<Evt>()
.id(id)
.entity(e1)
.emit();
test_int(count, 1);
}
void Event_evt_1_component(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<IdA>();
int32_t count = 0;
ecs.observer()
.event<Evt>()
.term<IdA>()
.each([&](flecs::entity e) {
test_assert(e == e1);
count ++;
});
ecs.event<Evt>()
.id<IdA>()
.entity(e1)
.emit();
test_int(count, 1);
}
void Event_evt_2_components(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<IdA>().add<IdB>();
int32_t count = 0;
ecs.observer()
.event<Evt>()
.term<IdA>()
.each([&](flecs::entity e) {
test_assert(e == e1);
count ++;
});
ecs.observer()
.event<Evt>()
.term<IdB>()
.each([&](flecs::entity e) {
test_assert(e == e1);
count ++;
});
ecs.event<Evt>()
.id<IdA>()
.id<IdB>()
.entity(e1)
.emit();
test_int(count, 2);
}
struct EvtData {
int value;
};
void Event_evt_void_ctx(void) {
flecs::world ecs;
auto evt = ecs.entity();
auto id = ecs.entity();
auto e1 = ecs.entity().add(id);
int32_t count = 0;
ecs.observer()
.event(evt)
.term(id)
.iter([&](flecs::iter& it) {
test_assert(it.entity(0) == e1);
test_int(it.param<EvtData>()->value, 10);
count ++;
});
EvtData data = {10};
ecs.event(evt)
.id(id)
.entity(e1)
.ctx(&data)
.emit();
test_int(count, 1);
}
void Event_evt_typed_ctx(void) {
flecs::world ecs;
auto id = ecs.entity();
auto e1 = ecs.entity().add(id);
int32_t count = 0;
ecs.observer()
.event<EvtData>()
.term(id)
.iter([&](flecs::iter& it) {
test_assert(it.entity(0) == e1);
test_int(it.param<EvtData>()->value, 10);
count ++;
});
ecs.event<EvtData>()
.id(id)
.entity(e1)
.ctx(EvtData{10})
.emit();
test_int(count, 1);
}
void Event_evt_implicit_typed_ctx(void) {
flecs::world ecs;
auto id = ecs.entity();
auto e1 = ecs.entity().add(id);
int32_t count = 0;
ecs.observer()
.event<EvtData>()
.term(id)
.iter([&](flecs::iter& it) {
test_assert(it.entity(0) == e1);
test_int(it.param<EvtData>()->value, 10);
count ++;
});
ecs.event<EvtData>()
.id(id)
.entity(e1)
.ctx({10})
.emit();
test_int(count, 1);
}
void Event_evt_1_id_pair_rel_id_obj_id_entity(void) {
flecs::world ecs;
auto evt = ecs.entity();
auto rel = ecs.entity();
auto obj = ecs.entity();
auto e1 = ecs.entity().add(rel, obj);
int32_t count = 0;
ecs.observer()
.event(evt)
.term(rel, obj)
.each([&](flecs::entity e) {
test_assert(e == e1);
count ++;
});
ecs.event(evt)
.id(rel, obj)
.entity(e1)
.emit();
test_int(count, 1);
}
void Event_evt_1_id_pair_rel_obj_id_entity(void) {
flecs::world ecs;
auto evt = ecs.entity();
auto obj = ecs.entity();
auto e1 = ecs.entity().add<IdA>(obj);
int32_t count = 0;
ecs.observer()
.event(evt)
.term<IdA>(obj)
.each([&](flecs::entity e) {
test_assert(e == e1);
count ++;
});
ecs.event(evt)
.id<IdA>(obj)
.entity(e1)
.emit();
test_int(count, 1);
}
void Event_evt_1_id_pair_rel_obj_entity(void) {
flecs::world ecs;
auto evt = ecs.entity();
auto e1 = ecs.entity().add<IdA, IdB>();
int32_t count = 0;
ecs.observer()
.event(evt)
.term<IdA, IdB>()
.each([&](flecs::entity e) {
test_assert(e == e1);
count ++;
});
ecs.event(evt)
.id<IdA, IdB>()
.entity(e1)
.emit();
test_int(count, 1);
}
void Event_emit_staged_from_world(void) {
flecs::world ecs;
auto evt = ecs.entity();
auto e1 = ecs.entity().add<Tag>();
int32_t count = 0;
ecs.observer()
.event(evt)
.term<Tag>()
.each([&](flecs::entity e) {
test_assert(e == e1);
count ++;
});
ecs.readonly_begin();
ecs.event(evt)
.id<Tag>()
.entity(e1)
.emit();
ecs.readonly_end();
test_int(count, 1);
}
void Event_emit_staged_from_stage(void) {
flecs::world ecs;
auto evt = ecs.entity();
auto e1 = ecs.entity().add<Tag>();
int32_t count = 0;
ecs.observer()
.event(evt)
.term<Tag>()
.each([&](flecs::entity e) {
test_assert(e == e1);
count ++;
});
ecs.readonly_begin();
ecs.get_stage(0).event(evt)
.id<Tag>()
.entity(e1)
.emit();
ecs.readonly_end();
test_int(count, 1);
}
void Event_emit_custom_for_any(void) {
flecs::world ecs;
int count_a = 0;
int count_b = 0;
flecs::entity e1 = ecs.entity().add<Tag>();
flecs::entity e2 = ecs.entity().add<Tag>();
ecs.observer()
.event<Evt>()
.with(flecs::Any).src(e1)
.each([&](flecs::entity e) {
test_assert(e == 0);
count_a ++;
});
ecs.observer()
.event<Evt>()
.with(flecs::Any).src(e2)
.each([&](flecs::entity e) {
test_assert(e == 0);
count_b ++;
});
ecs.event<Evt>()
.id(flecs::Any)
.entity(e1)
.emit();
test_int(count_a, 1);
test_int(count_b, 0);
ecs.event<Evt>()
.id(flecs::Any)
.entity(e2)
.emit();
test_int(count_a, 1);
test_int(count_b, 1);
}
void Event_entity_emit_event_id(void) {
flecs::world ecs;
flecs::entity evt = ecs.entity();
flecs::entity e = ecs.entity()
.add<Tag>();
int32_t count = 0;
e.observe(evt, [&](flecs::entity src) {
count ++;
test_assert(src == e);
});
test_int(count, 0);
e.emit(evt);
test_int(count, 1);
}
void Event_entity_emit_event_type(void) {
flecs::world ecs;
flecs::entity e = ecs.entity()
.add<Tag>();
int32_t count = 0;
e.observe<Evt>([&](flecs::entity src) {
count ++;
test_assert(src == e);
});
test_int(count, 0);
e.emit<Evt>();
test_int(count, 1);
}
void Event_entity_emit_event_w_payload(void) {
flecs::world ecs;
flecs::entity e = ecs.entity()
.add<Tag>();
int32_t count = 0;
e.observe<Position>([&](flecs::entity src, Position& p) {
count ++;
test_assert(src == e);
test_int(p.x, 10);
test_int(p.y, 20);
});
test_int(count, 0);
e.emit<Position>({10, 20});
test_int(count, 1);
}
void Event_entity_emit_event_id_no_src(void) {
flecs::world ecs;
flecs::entity evt = ecs.entity();
flecs::entity e = ecs.entity()
.add<Tag>();
int32_t count = 0;
e.observe(evt, [&]() {
count ++;
});
test_int(count, 0);
e.emit(evt);
test_int(count, 1);
}
void Event_entity_emit_event_type_no_src(void) {
flecs::world ecs;
flecs::entity e = ecs.entity()
.add<Tag>();
int32_t count = 0;
e.observe<Evt>([&]() {
count ++;
});
test_int(count, 0);
e.emit<Evt>();
test_int(count, 1);
}
void Event_entity_emit_event_w_payload_no_src(void) {
flecs::world ecs;
flecs::entity e = ecs.entity()
.add<Tag>();
int32_t count = 0;
e.observe<Position>([&](Position& p) {
count ++;
test_int(p.x, 10);
test_int(p.y, 20);
});
test_int(count, 0);
e.emit<Position>({10, 20});
test_int(count, 1);
}
void Event_entity_emit_event_w_payload_derived_event_type(void) {
flecs::world ecs;
flecs::entity e = ecs.entity()
.add<Tag>();
int32_t count = 0;
e.observe([&](flecs::entity src, Position& p) {
count ++;
test_assert(src == e);
test_int(p.x, 10);
test_int(p.y, 20);
});
test_int(count, 0);
e.emit<Position>({10, 20});
test_int(count, 1);
}
void Event_entity_emit_event_w_payload_derived_event_type_no_src(void) {
flecs::world ecs;
flecs::entity e = ecs.entity()
.add<Tag>();
int32_t count = 0;
e.observe([&](Position& p) {
count ++;
test_int(p.x, 10);
test_int(p.y, 20);
});
test_int(count, 0);
e.emit<Position>({10, 20});
test_int(count, 1);
}

View File

@@ -0,0 +1,551 @@
#include <cpp_api.h>
void Filter_term_each_component(void) {
flecs::world ecs;
auto e_1 = ecs.entity().set<Position>({1, 2});
auto e_2 = ecs.entity().set<Position>({3, 4});
auto e_3 = ecs.entity().set<Position>({5, 6});
e_3.add<Tag>();
int32_t count = 0;
ecs.each<Position>([&](flecs::entity e, Position& p) {
if (e == e_1) {
test_int(p.x, 1);
test_int(p.y, 2);
count ++;
}
if (e == e_2) {
test_int(p.x, 3);
test_int(p.y, 4);
count ++;
}
if (e == e_3) {
test_int(p.x, 5);
test_int(p.y, 6);
count ++;
}
});
test_int(count, 3);
}
void Filter_term_each_tag(void) {
flecs::world ecs;
struct Foo { };
auto e_1 = ecs.entity().add<Foo>();
auto e_2 = ecs.entity().add<Foo>();
auto e_3 = ecs.entity().add<Foo>();
e_3.add<Tag>();
int32_t count = 0;
ecs.each<Foo>([&](flecs::entity e, Foo) {
if (e == e_1 || e == e_2 || e == e_3) {
count ++;
}
});
test_int(count, 3);
}
void Filter_term_each_id(void) {
flecs::world ecs;
auto foo = ecs.entity();
auto e_1 = ecs.entity().add(foo);
auto e_2 = ecs.entity().add(foo);
auto e_3 = ecs.entity().add(foo);
e_3.add<Tag>();
int32_t count = 0;
ecs.each(foo, [&](flecs::entity e) {
if (e == e_1 || e == e_2 || e == e_3) {
count ++;
}
});
test_int(count, 3);
}
void Filter_term_each_pair_type(void) {
flecs::world ecs;
struct Rel { };
struct Obj { };
auto e_1 = ecs.entity().add<Rel, Obj>();
auto e_2 = ecs.entity().add<Rel, Obj>();
auto e_3 = ecs.entity().add<Rel, Obj>();
e_3.add<Tag>();
int32_t count = 0;
ecs.each<flecs::pair<Rel, Obj>>([&](flecs::entity e, flecs::pair<Rel,Obj>) {
if (e == e_1 || e == e_2 || e == e_3) {
count ++;
}
});
test_int(count, 3);
}
void Filter_term_each_pair_id(void) {
flecs::world ecs;
auto rel = ecs.entity();
auto obj = ecs.entity();
auto e_1 = ecs.entity().add(rel, obj);
auto e_2 = ecs.entity().add(rel, obj);
auto e_3 = ecs.entity().add(rel, obj);
e_3.add<Tag>();
int32_t count = 0;
ecs.each(ecs.pair(rel, obj), [&](flecs::entity e) {
if (e == e_1 || e == e_2 || e == e_3) {
count ++;
}
});
test_int(count, 3);
}
void Filter_term_each_pair_relation_wildcard(void) {
flecs::world ecs;
auto rel_1 = ecs.entity();
auto rel_2 = ecs.entity();
auto obj = ecs.entity();
auto e_1 = ecs.entity().add(rel_1, obj);
auto e_2 = ecs.entity().add(rel_1, obj);
auto e_3 = ecs.entity().add(rel_2, obj);
e_3.add<Tag>();
int32_t count = 0;
ecs.each(ecs.pair(flecs::Wildcard, obj), [&](flecs::entity e) {
if (e == e_1 || e == e_2 || e == e_3) {
count ++;
}
});
test_int(count, 3);
}
void Filter_term_each_pair_object_wildcard(void) {
flecs::world ecs;
auto rel = ecs.entity();
auto obj_1 = ecs.entity();
auto obj_2 = ecs.entity();
auto e_1 = ecs.entity().add(rel, obj_1);
auto e_2 = ecs.entity().add(rel, obj_1);
auto e_3 = ecs.entity().add(rel, obj_2);
e_3.add<Tag>();
int32_t count = 0;
ecs.each(ecs.pair(rel, flecs::Wildcard), [&](flecs::entity e) {
if (e == e_1 || e == e_2 || e == e_3) {
count ++;
}
});
test_int(count, 3);
}
void Filter_default_ctor_no_assign(void) {
flecs::filter<> f;
// Make sure code compiles & works
test_assert(true);
}
void Filter_term_get_id(void) {
flecs::world ecs;
auto Foo = ecs.entity();
auto Bar = ecs.entity();
auto q = ecs.query_builder()
.term<Position>()
.term<Velocity>()
.term(Foo, Bar)
.build();
test_int(q.field_count(), 3);
flecs::term
t = q.term(0);
test_assert(t.id() == ecs.id<Position>());
t = q.term(1);
test_assert(t.id() == ecs.id<Velocity>());
t = q.term(2);
test_assert(t.id() == ecs.pair(Foo, Bar));
}
void Filter_term_get_subj(void) {
flecs::world ecs;
auto Foo = ecs.entity();
auto Bar = ecs.entity();
auto Src = ecs.entity();
auto q = ecs.query_builder()
.term<Position>()
.term<Velocity>().src(Src)
.term(Foo, Bar)
.build();
test_int(q.field_count(), 3);
flecs::term
t = q.term(0);
test_assert(t.get_src() == flecs::This);
t = q.term(1);
test_assert(t.get_src() == Src);
t = q.term(2);
test_assert(t.get_src() == flecs::This);
}
void Filter_term_get_pred(void) {
flecs::world ecs;
auto Foo = ecs.entity();
auto Bar = ecs.entity();
auto Src = ecs.entity();
auto q = ecs.query_builder()
.term<Position>()
.term<Velocity>().src(Src)
.term(Foo, Bar)
.build();
test_int(q.field_count(), 3);
flecs::term
t = q.term(0);
test_assert(t.get_first() == ecs.id<Position>());
t = q.term(1);
test_assert(t.get_first() == ecs.id<Velocity>());
t = q.term(2);
test_assert(t.get_first() == Foo);
}
void Filter_term_get_obj(void) {
flecs::world ecs;
auto Foo = ecs.entity();
auto Bar = ecs.entity();
auto Src = ecs.entity();
auto q = ecs.query_builder()
.term<Position>()
.term<Velocity>().src(Src)
.term(Foo, Bar)
.build();
test_int(q.field_count(), 3);
flecs::term
t = q.term(0);
test_assert(t.get_second() == 0);
t = q.term(1);
test_assert(t.get_second() == 0);
t = q.term(2);
test_assert(t.get_second() == Bar);
}
void Filter_get_first(void) {
flecs::world ecs;
struct A {};
auto e1 = ecs.entity().add<A>();
ecs.entity().add<A>();
ecs.entity().add<A>();
auto q = ecs.filter<A>();
auto first = q.iter().first();
test_assert(first != 0);
test_assert(first == e1);
}
void Filter_get_count_direct(void) {
flecs::world ecs;
struct A {};
ecs.entity().add<A>();
ecs.entity().add<A>();
ecs.entity().add<A>();
auto q = ecs.filter<A>();
test_int(3, q.count());
}
void Filter_get_is_true_direct(void) {
flecs::world ecs;
struct A {};
struct B {};
ecs.entity().add<A>();
ecs.entity().add<A>();
ecs.entity().add<A>();
auto q_1 = ecs.filter<A>();
auto q_2 = ecs.filter<B>();
test_bool(true, q_1.is_true());
test_bool(false, q_2.is_true());
}
void Filter_get_first_direct(void) {
flecs::world ecs;
struct A {};
auto e1 = ecs.entity().add<A>();
ecs.entity().add<A>();
ecs.entity().add<A>();
auto q = ecs.filter<A>();
auto first = q.first();
test_assert(first != 0);
test_assert(first == e1);
}
void Filter_each_w_no_this(void) {
flecs::world ecs;
auto e = ecs.entity()
.set<Position>({10, 20})
.set<Velocity>({1, 2});
auto f = ecs.filter_builder<Position, Velocity>()
.arg(1).src(e)
.arg(2).src(e)
.build();
int32_t count = 0;
f.each([&](Position& p, Velocity& v) {
count ++;
test_int(p.x, 10);
test_int(p.y, 20);
test_int(v.x, 1);
test_int(v.y, 2);
});
test_int(count, 1);
}
void Filter_each_w_iter_no_this(void) {
flecs::world ecs;
auto e = ecs.entity()
.set<Position>({10, 20})
.set<Velocity>({1, 2});
auto f = ecs.filter_builder<Position, Velocity>()
.arg(1).src(e)
.arg(2).src(e)
.build();
int32_t count = 0;
f.each([&](flecs::iter& it, size_t index, Position& p, Velocity& v) {
count ++;
test_int(p.x, 10);
test_int(p.y, 20);
test_int(v.x, 1);
test_int(v.y, 2);
test_int(index, 0);
test_int(it.count(), 0);
});
test_int(count, 1);
}
void Filter_invalid_each_w_no_this(void) {
install_test_abort();
flecs::world ecs;
auto e = ecs.entity()
.set<Position>({10, 20})
.set<Velocity>({1, 2});
auto f = ecs.filter_builder<Position, Velocity>()
.arg(1).src(e)
.arg(2).src(e)
.build();
test_expect_abort();
f.each([&](flecs::entity e, Position& p, Velocity& v) { });
}
void Filter_named_filter(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>();
auto e2 = ecs.entity().add<Position>();
auto q = ecs.filter<Position>("my_query");
int32_t count = 0;
q.each([&](flecs::entity e, Position&) {
test_assert(e == e1 || e == e2);
count ++;
});
test_int(count, 2);
flecs::entity qe = q.entity();
test_assert(qe != 0);
test_str(qe.name(), "my_query");
}
void Filter_named_scoped_filter(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>();
auto e2 = ecs.entity().add<Position>();
auto q = ecs.filter<Position>("my::query");
int32_t count = 0;
q.each([&](flecs::entity e, Position&) {
test_assert(e == e1 || e == e2);
count ++;
});
test_int(count, 2);
flecs::entity qe = q.entity();
test_assert(qe != 0);
test_str(qe.name(), "query");
test_str(qe.path(), "::my::query");
}
void Filter_set_this_var(void) {
flecs::world ecs;
/* auto e_1 = */ ecs.entity().set<Position>({1, 2});
auto e_2 = ecs.entity().set<Position>({3, 4});
/* auto e_3 = */ ecs.entity().set<Position>({5, 6});
auto q = ecs.filter<Position>("my::query");
int32_t count = 0;
q.iter().set_var(0, e_2).each([&](flecs::entity e, Position&) {
test_assert(e == e_2);
count ++;
});
test_int(count, 1);
}
void Filter_inspect_terms_w_expr(void) {
flecs::world ecs;
flecs::filter<> f = ecs.filter_builder()
.expr("(ChildOf,0)")
.build();
int32_t count = 0;
f.each_term([&](flecs::term &term) {
test_assert(term.id().is_pair());
count ++;
});
test_int(count, 1);
}
void Filter_find(void) {
flecs::world ecs;
/* auto e1 = */ ecs.entity().set<Position>({10, 20});
auto e2 = ecs.entity().set<Position>({20, 30});
auto q = ecs.filter<Position>();
auto r = q.find([](Position& p) {
return p.x == 20;
});
test_assert(r == e2);
}
void Filter_find_not_found(void) {
flecs::world ecs;
/* auto e1 = */ ecs.entity().set<Position>({10, 20});
/* auto e2 = */ ecs.entity().set<Position>({20, 30});
auto q = ecs.filter<Position>();
auto r = q.find([](Position& p) {
return p.x == 30;
});
test_assert(!r);
}
void Filter_find_w_entity(void) {
flecs::world ecs;
/* auto e1 = */ ecs.entity().set<Position>({10, 20}).set<Velocity>({20, 30});
auto e2 = ecs.entity().set<Position>({20, 30}).set<Velocity>({20, 30});
auto q = ecs.filter<Position>();
auto r = q.find([](flecs::entity e, Position& p) {
return p.x == e.get<Velocity>()->x &&
p.y == e.get<Velocity>()->y;
});
test_assert(r == e2);
}
void Filter_optional_pair_term(void) {
flecs::world ecs;
ecs.entity()
.add<TagA>()
.emplace<Position, Tag>(1.0f, 2.0f);
ecs.entity()
.add<TagA>();
int32_t with_pair = 0, without_pair = 0;
auto f = ecs.filter_builder<flecs::pair<Position, Tag>*>()
.with<TagA>()
.build();
f.each([&](flecs::entity e, Position* p) {
if (p) {
with_pair++;
test_flt(1.0f, p->x);
test_flt(2.0f, p->y);
} else {
without_pair++;
}
});
ecs.progress(1.0);
test_int(1, with_pair);
test_int(1, without_pair);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,489 @@
#include <cpp_api.h>
struct Pair {
int value;
};
void ImplicitComponents_add(void) {
flecs::world world;
auto e = world.entity().add<Position>();
test_str(e.type().str().c_str(), "Position");
test_assert(e.has<Position>());
auto position = world.lookup("Position");
test_assert(position.id() != 0);
}
void ImplicitComponents_remove(void) {
flecs::world world;
auto e = world.entity().remove<Position>();
test_assert(!e.has<Position>());
auto position = world.lookup("Position");
test_assert(position.id() != 0);
}
void ImplicitComponents_has(void) {
flecs::world world;
auto e = world.entity();
test_assert(!e.has<Position>());
auto position = world.lookup("Position");
test_assert(position.id() != 0);
}
void ImplicitComponents_set(void) {
flecs::world world;
auto e = world.entity().set<Position>({10, 20});
test_str(e.type().str().c_str(), "Position");
test_assert(e.has<Position>());
auto *p = e.get<Position>();
test_int(p->x, 10);
test_int(p->y, 20);
auto position = world.lookup("Position");
test_assert(position.id() != 0);
}
void ImplicitComponents_get(void) {
flecs::world world;
auto e = world.entity();
auto *p = e.get<Position>();
test_assert(p == nullptr);
auto position = world.lookup("Position");
test_assert(position.id() != 0);
}
void ImplicitComponents_add_pair(void) {
flecs::world world;
auto e = world.entity().add<Pair, Position>();
test_str(e.type().str().c_str(), "(Pair,Position)");
test_assert((e.has<Pair, Position>()));
auto position = world.lookup("Position");
test_assert(position.id() != 0);
auto pair = world.lookup("Pair");
test_assert(pair.id() != 0);
}
void ImplicitComponents_remove_pair(void) {
flecs::world world;
auto e = world.entity().remove<Position, Pair>();
test_assert((!e.has<Position, Pair>()));
auto position = world.lookup("Position");
test_assert(position.id() != 0);
auto pair = world.lookup("Pair");
test_assert(pair.id() != 0);
}
void ImplicitComponents_module(void) {
flecs::world world;
world.module<Position>();
auto position = world.lookup("Position");
test_assert(position.id() != 0);
}
void ImplicitComponents_system(void) {
flecs::world world;
world.system<Position, Velocity>()
.each([](flecs::entity e, Position& p, Velocity& v) {
});
auto position = world.lookup("Position");
test_assert(position.id() != 0);
auto velocity = world.lookup("Velocity");
test_assert(velocity.id() != 0);
}
void ImplicitComponents_system_optional(void) {
flecs::world world;
int rotation_count = 0;
int mass_count = 0;
world.system<Rotation*, Mass*>()
.each([&](flecs::entity e, Rotation* r, Mass* m) {
if (r) {
rotation_count ++;
}
if (m) {
mass_count ++;
}
});
world.entity().set<Rotation>({10});
world.entity().set<Mass>({20});
world.entity()
.set<Rotation>({30})
.set<Mass>({40});
auto rotation = world.lookup("Rotation");
test_assert(rotation.id() != 0);
auto mass = world.lookup("Mass");
test_assert(mass.id() != 0);
auto rcomp = world.component<Rotation>();
test_assert(rcomp == rotation);
auto mcomp = world.component<Mass>();
test_assert(mcomp == mass);
world.progress();
test_int(rotation_count, 2);
test_int(mass_count, 2);
}
void ImplicitComponents_system_const(void) {
flecs::world world;
int count = 0;
world.system<Position, const Velocity>()
.each([&](flecs::entity e, Position& p, const Velocity& v) {
p.x += v.x;
p.y += v.y;
count ++;
});
auto position = world.lookup("Position");
test_assert(position.id() != 0);
auto velocity = world.lookup("Velocity");
test_assert(velocity.id() != 0);
auto e = world.entity()
.set<Position>({10, 20})
.set<Velocity>({1, 2});
auto pcomp = world.component<Position>();
test_assert(pcomp == position);
auto vcomp = world.component<Velocity>();
test_assert(vcomp == velocity);
world.progress();
test_int(count, 1);
const Position *p = e.get<Position>();
test_int(p->x, 11);
test_int(p->y, 22);
}
void ImplicitComponents_query(void) {
flecs::world world;
auto q = world.query<Position, Velocity>();
q.each([](flecs::entity e, Position& p, Velocity &v) { });
auto position = world.lookup("Position");
test_assert(position.id() != 0);
auto velocity = world.lookup("Velocity");
test_assert(velocity.id() != 0);
}
void ImplicitComponents_implicit_name(void) {
flecs::world world;
auto pcomp = world.component<Position>();
auto position = world.lookup("Position");
test_assert(position.id() != 0);
test_assert(pcomp == position);
}
void ImplicitComponents_reinit(void) {
flecs::world world;
auto comp_1 = world.component<Position>();
test_assert(flecs::type_id<Position>() == comp_1.id());
// Reset component id using internals (currently the only way to simulate
// registration across translation units)
flecs::_::cpp_type<Position>::reset();
world.entity()
.add<Position>();
test_assert(flecs::type_id<Position>() == comp_1.id());
}
namespace Foo {
struct Position {
float x;
float y;
};
}
void ImplicitComponents_reinit_scoped(void) {
flecs::world world;
auto comp_1 = world.component<Foo::Position>();
test_assert(flecs::type_id<Foo::Position>() == comp_1.id());
// Reset component id using internals (currently the only way to simulate
// registration across translation units)
flecs::_::cpp_type<Foo::Position>::reset();
world.entity()
.add<Foo::Position>();
test_assert(flecs::type_id<Foo::Position>() == comp_1.id());
}
static int position_ctor_invoked = 0;
ECS_CTOR(Position, ptr, {
position_ctor_invoked ++;
})
void ImplicitComponents_reinit_w_lifecycle(void) {
flecs::world world;
auto comp_1 = world.component<Position>();
test_assert(flecs::type_id<Position>() == comp_1.id());
// Explicitly register constructor
ecs_type_hooks_t cl{};
cl.ctor = ecs_ctor(Position);
ecs_set_hooks_id(world.c_ptr(), comp_1.id(), &cl);
auto e = world.entity()
.add<Position>();
test_assert(e.has<Position>());
test_int(position_ctor_invoked, 1);
// Reset component id using internals (currently the only way to simulate
// registration across translation units)
flecs::_::cpp_type<Position>::reset();
e = world.entity()
.add<Position>();
test_assert(e.has<Position>());
test_int(position_ctor_invoked, 2);
test_assert(flecs::type_id<Position>() == comp_1.id());
}
void ImplicitComponents_first_use_in_system(void) {
flecs::world world;
world.system<Position>()
.each([](flecs::entity e, Position& p) {
e.add<Velocity>();
});
auto e = world.entity().add<Position>();
world.progress();
test_assert(e.has<Velocity>());
}
namespace ns {
struct NsTag { };
}
void ImplicitComponents_first_use_tag_in_system(void) {
flecs::world world;
world.system<Position>()
.each([](flecs::entity e, Position& p) {
e.add<Tag>();
e.add<ns::NsTag>();
});
auto e = world.entity().add<Position>();
world.progress();
test_assert(e.has<Tag>());
}
enum Color {
Red,
Green,
Blue
};
void ImplicitComponents_first_use_enum_in_system(void) {
flecs::world world;
world.system<Position>()
.each([](flecs::entity e, Position& p) {
e.add<Tag>();
e.add(Color::Green);
});
auto e = world.entity().add<Position>();
world.progress();
test_assert(e.has<Position>());
test_assert(e.has<Tag>());
test_assert(e.has(Color::Green));
test_assert(world.component<Color>().has(flecs::Exclusive));
}
void ImplicitComponents_use_const(void) {
flecs::world world;
world.use<const Position>();
auto e = world.entity()
.set<Position>({10, 20});
test_assert(e.has<Position>());
const Position *p = e.get<Position>();
test_int(p->x, 10);
test_int(p->y, 20);
}
void ImplicitComponents_use_const_w_stage(void) {
flecs::world world;
world.use<const Velocity>();
auto e = world.entity()
.set<Position>({10, 20});
world.system<Position>()
.each([](flecs::entity e, Position&) {
e.set<Velocity>({1, 2});
});
world.progress();
test_assert(e.has<Velocity>());
const Velocity *v = e.get<Velocity>();
test_int(v->x, 1);
test_int(v->y, 2);
}
void ImplicitComponents_use_const_w_threads(void) {
flecs::world world;
world.use<const Velocity>();
auto e = world.entity()
.set<Position>({10, 20});
world.system<Position>()
.each([](flecs::entity e, Position&) {
e.set<Velocity>({1, 2});
});
world.set_threads(2);
world.progress();
test_assert(e.has<Velocity>());
const Velocity *v = e.get<Velocity>();
test_int(v->x, 1);
test_int(v->y, 2);
}
void ImplicitComponents_implicit_base(void) {
flecs::world world;
auto v = world.use<Position>();
test_int(v.id(), flecs::type_id<Position>());
test_int(v.id(), flecs::type_id<const Position>());
test_int(v.id(), flecs::type_id<Position*>());
test_int(v.id(), flecs::type_id<Position&>());
}
void ImplicitComponents_implicit_const(void) {
flecs::world world;
auto v = world.use<const Position>();
test_int(v.id(), flecs::type_id<Position>());
test_int(v.id(), flecs::type_id<const Position>());
test_int(v.id(), flecs::type_id<Position*>());
test_int(v.id(), flecs::type_id<Position&>());
}
void ImplicitComponents_implicit_ref(void) {
flecs::world world;
auto v = world.use<Position&>();
test_int(v.id(), flecs::type_id<Position>());
test_int(v.id(), flecs::type_id<const Position>());
test_int(v.id(), flecs::type_id<Position*>());
test_int(v.id(), flecs::type_id<Position&>());
}
void ImplicitComponents_implicit_ptr(void) {
flecs::world world;
auto v = world.use<Position*>();
test_int(v.id(), flecs::type_id<Position>());
test_int(v.id(), flecs::type_id<const Position>());
test_int(v.id(), flecs::type_id<Position*>());
test_int(v.id(), flecs::type_id<Position&>());
}
void ImplicitComponents_implicit_const_ref(void) {
flecs::world world;
auto v = world.use<const Position&>();
test_int(v.id(), flecs::type_id<Position>());
test_int(v.id(), flecs::type_id<const Position>());
test_int(v.id(), flecs::type_id<Position*>());
test_int(v.id(), flecs::type_id<Position&>());
}
void ImplicitComponents_vector_elem_type(void) {
flecs::world world;
{
flecs::entity v = world.vector<int>();
test_assert(v != 0);
}
flecs::reset();
{
flecs::entity v = world.vector<int>();
test_assert(v != 0);
}
}

View File

@@ -0,0 +1,120 @@
#include <cpp_api.h>
void Iterable_page_each(void) {
flecs::world ecs;
auto e1 = ecs.entity(); e1.set<Self>({e1});
auto e2 = ecs.entity(); e2.set<Self>({e2});
auto e3 = ecs.entity(); e3.set<Self>({e3});
auto e4 = ecs.entity(); e4.set<Self>({e4});
auto e5 = ecs.entity(); e5.set<Self>({e5});
auto q = ecs.query<Self>();
int32_t count = 0;
q.page(1, 3).each([&](flecs::entity e, Self& self) {
count ++;
test_assert(e != e1);
test_assert(e != e5);
test_assert(e == self.value);
});
test_int(count, 3);
}
void Iterable_page_iter(void) {
flecs::world ecs;
auto e1 = ecs.entity(); e1.set<Self>({e1});
auto e2 = ecs.entity(); e2.set<Self>({e2});
auto e3 = ecs.entity(); e3.set<Self>({e3});
auto e4 = ecs.entity(); e4.set<Self>({e4});
auto e5 = ecs.entity(); e5.set<Self>({e5});
auto q = ecs.query<Self>();
int32_t count = 0;
q.page(1, 3).iter([&](flecs::iter it, Self* self) {
test_int(it.count(), 3);
test_assert(it.entity(0) == e2);
test_assert(it.entity(1) == e3);
test_assert(it.entity(2) == e4);
test_assert(it.entity(0) == self[0].value);
test_assert(it.entity(1) == self[1].value);
test_assert(it.entity(2) == self[2].value);
count += it.count();
});
test_int(count, 3);
}
void Iterable_worker_each(void) {
flecs::world ecs;
auto e1 = ecs.entity(); e1.set<Self>({e1});
auto e2 = ecs.entity(); e2.set<Self>({e2});
auto e3 = ecs.entity(); e3.set<Self>({e3});
auto e4 = ecs.entity(); e4.set<Self>({e4});
auto e5 = ecs.entity(); e5.set<Self>({e5});
auto q = ecs.query<Self>();
int32_t count = 0;
q.worker(0, 2).each([&](flecs::entity e, Self& self) {
count ++;
test_assert(e != e4);
test_assert(e != e5);
test_assert(e == self.value);
});
test_int(count, 3);
count = 0;
q.worker(1, 2).each([&](flecs::entity e, Self& self) {
count ++;
test_assert(e != e1);
test_assert(e != e2);
test_assert(e != e3);
test_assert(e == self.value);
});
test_int(count, 2);
}
void Iterable_worker_iter(void) {
flecs::world ecs;
auto e1 = ecs.entity(); e1.set<Self>({e1});
auto e2 = ecs.entity(); e2.set<Self>({e2});
auto e3 = ecs.entity(); e3.set<Self>({e3});
auto e4 = ecs.entity(); e4.set<Self>({e4});
auto e5 = ecs.entity(); e5.set<Self>({e5});
auto q = ecs.query<Self>();
int32_t count = 0;
q.worker(0, 2).iter([&](flecs::iter it, Self* self) {
test_int(it.count(), 3);
test_assert(it.entity(0) == e1);
test_assert(it.entity(1) == e2);
test_assert(it.entity(2) == e3);
test_assert(it.entity(0) == self[0].value);
test_assert(it.entity(1) == self[1].value);
test_assert(it.entity(2) == self[2].value);
count += it.count();
});
test_int(count, 3);
count = 0;
q.worker(1, 2).iter([&](flecs::iter it, Self* self) {
test_int(it.count(), 2);
test_assert(it.entity(0) == e4);
test_assert(it.entity(1) == e5);
test_assert(it.entity(0) == self[0].value);
test_assert(it.entity(1) == self[1].value);
count += it.count();
});
test_int(count, 2);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,278 @@
#include <cpp_api.h>
namespace ns {
struct NestedNameSpaceType { };
class NestedModule {
public:
NestedModule(flecs::world& world) {
world.module<ns::NestedModule>();
flecs::component<Velocity>(world, "Velocity");
}
};
class SimpleModule {
public:
SimpleModule(flecs::world& world) {
world.module<ns::SimpleModule>();
world.import<ns::NestedModule>();
flecs::component<Position>(world, "Position");
}
};
class NestedTypeModule {
public:
struct NestedType { };
NestedTypeModule(flecs::world& world) {
world.module<NestedTypeModule>();
world.component<NestedType>();
world.component<NestedNameSpaceType>();
}
};
class NamedModule {
public:
NamedModule(flecs::world& world) {
world.module<ns::NamedModule>("::my_scope::NamedModule");
flecs::component<Position>(world, "Position");
}
};
class ImplicitModule {
public:
ImplicitModule(flecs::world& world) {
world.component<Position>();
}
};
class NamedModuleInRoot {
public:
NamedModuleInRoot(flecs::world& world) {
world.module<NamedModuleInRoot>("::NamedModuleInRoot");
world.component<Position>();
}
};
}
struct Module {
Module(flecs::world& world) {
world.module<Module>();
world.component<Position>();
}
};
void Module_import(void) {
flecs::world world;
auto m = world.import<ns::SimpleModule>();
test_assert(m.id() != 0);
test_str(m.path().c_str(), "::ns::SimpleModule");
test_assert(m.has(flecs::Module));
auto e = flecs::entity(world)
.add<Position>();
test_assert(e.id() != 0);
test_assert(e.has<Position>());
}
void Module_lookup_from_scope(void) {
flecs::world world;
world.import<ns::SimpleModule>();
auto ns_entity = world.lookup("ns");
test_assert(ns_entity.id() != 0);
auto module_entity = world.lookup("ns::SimpleModule");
test_assert(module_entity.id() != 0);
auto position_entity = world.lookup("ns::SimpleModule::Position");
test_assert(position_entity.id() != 0);
auto nested_module = ns_entity.lookup("SimpleModule");
test_assert(module_entity.id() == nested_module.id());
auto module_position = module_entity.lookup("Position");
test_assert(position_entity.id() == module_position.id());
auto ns_position = ns_entity.lookup("SimpleModule::Position");
test_assert(position_entity.id() == ns_position.id());
}
void Module_nested_module(void) {
flecs::world world;
world.import<ns::SimpleModule>();
auto velocity = world.lookup("ns::NestedModule::Velocity");
test_assert(velocity.id() != 0);
test_str(velocity.path().c_str(), "::ns::NestedModule::Velocity");
}
void Module_nested_type_module(void) {
flecs::world world;
world.import<ns::NestedTypeModule>();
auto ns_entity = world.lookup("ns");
test_assert(ns_entity.id() != 0);
auto module_entity = world.lookup("ns::NestedTypeModule");
test_assert(module_entity.id() != 0);
auto type_entity = world.lookup("ns::NestedTypeModule::NestedType");
test_assert(type_entity.id() != 0);
auto ns_type_entity = world.lookup("ns::NestedTypeModule::NestedNameSpaceType");
test_assert(ns_type_entity.id() != 0);
int32_t childof_count = 0;
type_entity.each(flecs::ChildOf, [&](flecs::entity) {
childof_count ++;
});
test_int(childof_count, 1);
childof_count = 0;
ns_type_entity.each(flecs::ChildOf, [&](flecs::entity) {
childof_count ++;
});
test_int(childof_count, 1);
}
void Module_component_redefinition_outside_module(void) {
flecs::world world;
world.import<ns::SimpleModule>();
auto pos_comp = world.lookup("ns::SimpleModule::Position");
test_assert(pos_comp.id() != 0);
auto pos = world.component<Position>();
test_assert(pos.id() != 0);
test_assert(pos.id() == pos_comp.id());
int32_t childof_count = 0;
pos_comp.each(flecs::ChildOf, [&](flecs::entity) {
childof_count ++;
});
test_int(childof_count, 1);
}
void Module_module_tag_on_namespace(void) {
flecs::world world;
auto mid = world.import<ns::NestedModule>();
test_assert(mid.has(flecs::Module));
auto nsid = world.lookup("ns");
test_assert(nsid.has(flecs::Module));
}
static int module_ctor_invoked = 0;
static int module_dtor_invoked = 0;
class Module_w_dtor {
public:
Module_w_dtor(flecs::world& world) {
world.module<Module_w_dtor>();
module_ctor_invoked ++;
world.system<>().iter([](flecs::iter& it) { });
}
~Module_w_dtor() {
module_dtor_invoked ++;
}
};
void Module_dtor_on_fini(void) {
{
flecs::world ecs;
test_int(module_ctor_invoked, 0);
test_int(module_dtor_invoked, 0);
ecs.import<Module_w_dtor>();
test_int(module_ctor_invoked, 1);
test_int(module_dtor_invoked, 0);
}
test_int(module_dtor_invoked, 1);
}
void Module_register_w_root_name() {
flecs::world ecs;
auto m = ecs.import<ns::NamedModule>();
auto m_lookup = ecs.lookup("::my_scope::NamedModule");
test_assert(m != 0);
test_assert(m == m_lookup);
test_assert(ecs.lookup("::ns::NamedModule") == 0);
}
void Module_implicit_module(void) {
flecs::world ecs;
auto m = ecs.import<ns::ImplicitModule>();
auto m_lookup = ecs.lookup("::ns::ImplicitModule");
test_assert(m != 0);
test_assert(m == m_lookup);
auto p = ecs.component<Position>();
auto p_lookup = ecs.lookup("::ns::ImplicitModule::Position");
test_assert(p != 0);
test_assert(p == p_lookup);
}
void Module_module_in_namespace_w_root_name(void) {
flecs::world ecs;
auto m = ecs.import<ns::NamedModuleInRoot>();
auto m_lookup = ecs.lookup("::NamedModuleInRoot");
test_assert(m != 0);
test_assert(m == m_lookup);
test_str(m.path(), "::NamedModuleInRoot");
auto p = ecs.component<Position>();
auto p_lookup = ecs.lookup("::NamedModuleInRoot::Position");
test_assert(p != 0);
test_assert(p == p_lookup);
}
void Module_module_as_entity(void) {
flecs::world world;
auto m = world.import<ns::SimpleModule>();
test_assert(m != 0);
auto e = world.entity<ns::SimpleModule>();
test_assert(m == e);
}
void Module_module_as_component(void) {
flecs::world world;
auto m = world.import<ns::SimpleModule>();
test_assert(m != 0);
auto e = world.component<ns::SimpleModule>();
test_assert(m == e);
}
void Module_module_with_core_name(void) {
flecs::world world;
flecs::entity m = world.import<Module>();
test_assert(m != 0);
test_str(m.path().c_str(), "::Module");
flecs::entity pos = m.lookup("Position");
test_assert(pos != 0);
test_str(pos.path().c_str(), "::Module::Position");
test_assert(pos == world.id<Position>());
}

View File

@@ -0,0 +1,818 @@
#include <cpp_api.h>
void Observer_2_terms_on_add(void) {
flecs::world ecs;
int32_t count = 0;
ecs.observer<Position, Velocity>()
.event(flecs::OnAdd)
.each([&](Position& p, Velocity& v) {
count ++;
});
auto e = ecs.entity();
test_int(count, 0);
e.set<Position>({10, 20});
test_int(count, 0);
e.set<Velocity>({1, 2});
test_int(count, 1);
}
void Observer_2_terms_on_remove(void) {
flecs::world ecs;
int32_t count = 0;
ecs.observer<Position, Velocity>()
.event(flecs::OnRemove)
.each([&](Position& p, Velocity& v) {
count ++;
test_int(p.x, 10);
test_int(p.y, 20);
test_int(v.x, 1);
test_int(v.y, 2);
});
auto e = ecs.entity();
test_int(count, 0);
e.set<Position>({10, 20});
test_int(count, 0);
e.set<Velocity>({1, 2});
test_int(count, 0);
e.remove<Velocity>();
test_int(count, 1);
e.remove<Position>();
test_int(count, 1);
}
void Observer_2_terms_on_set(void) {
flecs::world ecs;
int32_t count = 0;
ecs.observer<Position, Velocity>()
.event(flecs::OnSet)
.each([&](Position& p, Velocity& v) {
count ++;
test_int(p.x, 10);
test_int(p.y, 20);
test_int(v.x, 1);
test_int(v.y, 2);
});
auto e = ecs.entity();
test_int(count, 0);
e.set<Position>({10, 20});
test_int(count, 0);
e.set<Velocity>({1, 2});
test_int(count, 1);
}
void Observer_2_terms_un_set(void) {
flecs::world ecs;
int32_t count = 0;
ecs.observer<Position, Velocity>()
.event(flecs::UnSet)
.each([&](Position& p, Velocity& v) {
count ++;
test_int(p.x, 10);
test_int(p.y, 20);
test_int(v.x, 1);
test_int(v.y, 2);
});
auto e = ecs.entity();
test_int(count, 0);
e.set<Position>({10, 20});
test_int(count, 0);
e.set<Velocity>({1, 2});
test_int(count, 0);
e.remove<Velocity>();
test_int(count, 1);
e.remove<Position>();
test_int(count, 1);
}
void Observer_10_terms(void) {
flecs::world ecs;
int count = 0;
auto e = ecs.entity();
ecs.observer<>()
.event(flecs::OnAdd)
.term<TagA>()
.term<TagB>()
.term<TagC>()
.term<TagD>()
.term<TagE>()
.term<TagF>()
.term<TagG>()
.term<TagH>()
.term<TagI>()
.term<TagJ>()
.iter([&](flecs::iter& it) {
test_int(it.count(), 1);
test_assert(it.entity(0) == e);
test_int(it.field_count(), 10);
count ++;
});
e.add<TagA>()
.add<TagB>()
.add<TagC>()
.add<TagD>()
.add<TagE>()
.add<TagF>()
.add<TagG>()
.add<TagH>()
.add<TagI>()
.add<TagJ>();
test_int(count, 1);
}
void Observer_20_terms(void) {
flecs::world ecs;
int count = 0;
auto e = ecs.entity();
ecs.observer<>()
.event(flecs::OnAdd)
.term<TagA>()
.term<TagB>()
.term<TagC>()
.term<TagD>()
.term<TagE>()
.term<TagF>()
.term<TagG>()
.term<TagH>()
.term<TagI>()
.term<TagJ>()
.term<TagK>()
.term<TagL>()
.term<TagM>()
.term<TagN>()
.term<TagO>()
.term<TagP>()
.term<TagQ>()
.term<TagR>()
.term<TagS>()
.term<TagT>()
.iter([&](flecs::iter& it) {
test_int(it.count(), 1);
test_assert(it.entity(0) == e);
test_int(it.field_count(), 20);
count ++;
});
e.add<TagA>()
.add<TagB>()
.add<TagC>()
.add<TagD>()
.add<TagE>()
.add<TagF>()
.add<TagG>()
.add<TagH>()
.add<TagI>()
.add<TagJ>()
.add<TagK>()
.add<TagL>()
.add<TagM>()
.add<TagN>()
.add<TagO>()
.add<TagP>()
.add<TagQ>()
.add<TagR>()
.add<TagS>()
.add<TagT>();
test_int(count, 1);
}
void Observer_2_entities_iter(void) {
flecs::world ecs;
auto e1 = ecs.entity();
auto e2 = ecs.entity();
int32_t count = 0;
flecs::entity last;
ecs.observer<const Position>()
.event(flecs::OnSet)
.iter([&](flecs::iter& it, const Position *p) {
for (auto i : it) {
count ++;
if (it.entity(i) == e1) {
test_int(p[i].x, 10);
test_int(p[i].y, 20);
} else if (it.entity(i) == e2) {
test_int(p[i].x, 30);
test_int(p[i].y, 40);
} else {
test_assert(false);
}
last = it.entity(i);
}
});
e1.set<Position>({ 10, 20 });
test_int(count, 1);
test_assert(last == e1);
e2.set<Position>({ 30, 40 });
test_int(count, 2);
test_assert(last == e2);
}
void Observer_2_entities_table_column(void) {
flecs::world ecs;
auto e1 = ecs.entity();
auto e2 = ecs.entity();
int32_t count = 0;
flecs::entity last;
ecs.observer<const Position>()
.event(flecs::OnSet)
.iter([&](flecs::iter& it) {
auto p = it.range().get<Position>();
for (auto i : it) {
count ++;
if (it.entity(i) == e1) {
test_int(p[i].x, 10);
test_int(p[i].y, 20);
} else if (it.entity(i) == e2) {
test_int(p[i].x, 30);
test_int(p[i].y, 40);
} else {
test_assert(false);
}
last = it.entity(i);
}
});
e1.set<Position>({ 10, 20 });
test_int(count, 1);
test_assert(last == e1);
e2.set<Position>({ 30, 40 });
test_int(count, 2);
test_assert(last == e2);
}
void Observer_2_entities_each(void) {
flecs::world ecs;
auto e1 = ecs.entity();
auto e2 = ecs.entity();
int32_t count = 0;
flecs::entity last;
ecs.observer<const Position>()
.event(flecs::OnSet)
.each([&](flecs::entity e, const Position& p) {
count ++;
if (e == e1) {
test_int(p.x, 10);
test_int(p.y, 20);
} else if (e == e2) {
test_int(p.x, 30);
test_int(p.y, 40);
} else {
test_assert(false);
}
last = e;
});
e1.set<Position>({ 10, 20 });
test_int(count, 1);
test_assert(last == e1);
e2.set<Position>({ 30, 40 });
test_int(count, 2);
test_assert(last == e2);
}
void Observer_create_w_no_template_args(void) {
flecs::world ecs;
auto e1 = ecs.entity();
int32_t count = 0;
ecs.observer()
.term<Position>()
.event(flecs::OnAdd)
.each([&](flecs::entity e) {
test_assert(e == e1);
count ++;
});
e1.set<Position>({10, 20});
test_int(count, 1);
}
void Observer_yield_existing(void) {
flecs::world world;
struct TagA { };
struct TagB { };
auto e1 = world.entity().add<TagA>();
auto e2 = world.entity().add<TagA>();
auto e3 = world.entity().add<TagA>().add<TagB>();
int32_t count = 0;
world.observer<TagA>()
.event(flecs::OnAdd)
.yield_existing()
.each([&](flecs::entity e, TagA) {
if (e == e1) count ++;
if (e == e2) count += 2;
if (e == e3) count += 3;
});
test_int(count, 6);
}
void Observer_yield_existing_2_terms(void) {
flecs::world world;
struct TagA { };
struct TagB { };
auto e1 = world.entity().add<TagA>().add<TagB>();
auto e2 = world.entity().add<TagA>().add<TagB>();
auto e3 = world.entity().add<TagA>().add<TagB>().add<TagC>();
world.entity().add<TagA>();
world.entity().add<TagB>();
int32_t count = 0;
world.observer<TagA, TagB>()
.event(flecs::OnAdd)
.yield_existing()
.each([&](flecs::entity e, TagA, TagB) {
if (e == e1) count ++;
if (e == e2) count += 2;
if (e == e3) count += 3;
});
test_int(count, 6);
}
void Observer_default_ctor(void) {
flecs::world world;
struct TagA { };
flecs::observer o;
test_assert(o == 0);
int32_t count = 0;
o = world.observer<TagA>()
.event(flecs::OnAdd)
.each([&](flecs::entity e, TagA) {
count ++;
});
world.entity().add<TagA>();
test_int(count, 1);
}
void Observer_entity_ctor(void) {
flecs::world world;
struct TagA { };
flecs::observer o = world.observer<TagA>()
.event(flecs::OnAdd)
.each([&](flecs::entity e, TagA) { });
flecs::entity oe = o;
flecs::observer eo = world.observer(oe);
test_assert(eo == o);
}
void Observer_on_add(void) {
flecs::world world;
int invoked = 0;
world.observer<Position>()
.event(flecs::OnAdd)
.each([&](flecs::entity e, Position& p) {
invoked ++;
});
world.entity()
.add<Position>();
test_int(invoked, 1);
}
void Observer_on_remove(void) {
flecs::world world;
int invoked = 0;
world.observer<Position>()
.event(flecs::OnRemove)
.each([&](flecs::entity e, Position& p) {
invoked ++;
});
auto e = world.entity()
.add<Position>();
test_int(invoked, 0);
e.remove<Position>();
test_int(invoked, 1);
}
struct MyTag { };
void Observer_on_add_tag_action(void) {
flecs::world world;
int invoked = 0;
world.observer<MyTag>()
.event(flecs::OnAdd)
.iter([&](flecs::iter it, MyTag*) {
invoked ++;
});
world.entity()
.add<MyTag>();
test_int(invoked, 1);
}
void Observer_on_add_tag_iter(void) {
flecs::world world;
int invoked = 0;
world.observer<MyTag>()
.event(flecs::OnAdd)
.iter([&](flecs::iter it, MyTag*) {
invoked ++;
});
world.entity()
.add<MyTag>();
test_int(invoked, 1);
}
void Observer_on_add_tag_each(void) {
flecs::world world;
int invoked = 0;
world.observer<MyTag>()
.event(flecs::OnAdd)
.each([&](flecs::entity e, MyTag) {
invoked ++;
});
world.entity()
.add<MyTag>();
test_int(invoked, 1);
}
void Observer_on_add_expr(void) {
flecs::world world;
int invoked = 0;
world.component<Tag>();
world.observer<>().expr("Tag")
.event(flecs::OnAdd)
.each([&](flecs::entity e) {
invoked ++;
});
auto e = world.entity().add<Tag>();
test_int(invoked, 1);
e.remove<Tag>();
test_int(invoked, 1);
}
void Observer_observer_w_filter_term(void) {
flecs::world world;
flecs::entity TagA = world.entity();
flecs::entity TagB = world.entity();
int invoked = 0;
world.observer()
.term(TagA)
.term(TagB).filter()
.event(flecs::OnAdd)
.each([&](flecs::entity e) {
invoked ++;
});
flecs::entity e = world.entity();
test_int(invoked, 0);
e.add(TagB);
test_int(invoked, 0);
e.add(TagA);
test_int(invoked, 1);
e.remove(TagB);
test_int(invoked, 1);
e.add(TagB);
test_int(invoked, 1);
e.clear();
test_int(invoked, 1);
e.add(TagA);
test_int(invoked, 1);
}
void Observer_run_callback(void) {
flecs::world ecs;
int32_t count = 0;
ecs.observer<Position>()
.event(flecs::OnAdd)
.run([](flecs::iter_t *it) {
while (ecs_iter_next(it)) {
it->callback(it);
}
})
.each([&](Position& p) {
count ++;
});
auto e = ecs.entity();
test_int(count, 0);
e.set<Position>({10, 20});
test_int(count, 1);
}
void Observer_get_query(void) {
flecs::world world;
world.entity().set<Position>({0, 0});
world.entity().set<Position>({1, 0});
world.entity().set<Position>({2, 0});
int32_t count = 0;
auto sys = world.observer<const Position>()
.event(flecs::OnSet)
.each([&](flecs::entity e, const Position& p) {
// Not used
});
auto q = sys.query();
q.iter([&](flecs::iter &it) {
auto pos = it.field<const Position>(1);
for (auto i : it) {
test_int(i, pos[i].x);
count ++;
}
});
test_int(count, 3);
}
void Observer_on_set_w_set(void) {
flecs::world world;
int32_t count = 0;
world.observer<Position>()
.event(flecs::OnSet)
.each([&](flecs::entity e, Position& p) {
count ++;
});
flecs::entity e = world.entity();
test_int(count, 0);
e.set<Position>({10, 20});
test_int(count, 1);
}
void Observer_on_set_w_defer_set(void) {
flecs::world world;
int32_t count = 0;
world.observer<Position>()
.event(flecs::OnSet)
.each([&](flecs::entity e, Position& p) {
count ++;
});
flecs::entity e = world.entity();
test_int(count, 0);
world.defer_begin();
e.set<Position>({10, 20});
test_int(count, 0);
world.defer_end();
test_int(count, 1);
}
#include <iostream>
void Observer_on_add_singleton(void) {
flecs::world world;
int32_t count = 0;
world.observer<Position>()
.term_at(1).singleton()
.event(flecs::OnSet)
.each([&](Position& p) {
test_int(p.x, 10);
test_int(p.y, 20);
count ++;
});
world.set<Position>({10, 20});
test_int(count, 1);
}
void Observer_on_add_pair_singleton(void) {
flecs::world world;
int32_t count = 0;
flecs::entity tgt = world.entity();
world.observer<Position>()
.term_at(1).second(tgt).singleton()
.event(flecs::OnSet)
.each([&](Position& p) {
test_int(p.x, 10);
test_int(p.y, 20);
count ++;
});
world.set<Position>(tgt, {10, 20});
test_int(count, 1);
}
void Observer_on_add_pair_wildcard_singleton(void) {
flecs::world world;
int32_t count = 0;
flecs::entity tgt_1 = world.entity();
flecs::entity tgt_2 = world.entity();
world.observer<Position>()
.term_at(1).second(flecs::Wildcard).singleton()
.event(flecs::OnSet)
.each([&](Position& p) {
test_int(p.x, 10);
test_int(p.y, 20);
count ++;
});
world.set<Position>(tgt_1, {10, 20});
test_int(count, 1);
world.set<Position>(tgt_2, {10, 20});
test_int(count, 2);
}
void Observer_on_add_with_pair_singleton(void) {
flecs::world world;
int32_t count = 0;
flecs::entity tgt = world.entity();
world.observer()
.with<Position>(tgt).singleton()
.event(flecs::OnSet)
.each([&](flecs::entity) {
count ++;
});
world.set<Position>(tgt, {10, 20});
test_int(count, 1);
}
void Observer_add_in_yield_existing(void) {
flecs::world world;
flecs::entity e1 = world.entity().set<Position>({});
flecs::entity e2 = world.entity().set<Position>({});
flecs::entity e3 = world.entity().set<Position>({});
world.observer()
.with<Position>()
.event(flecs::OnAdd)
.yield_existing()
.each([](flecs::entity e) {
e.add<Velocity>();
});
test_assert(e1.has<Position>());
test_assert(e1.has<Velocity>());
test_assert(e2.has<Position>());
test_assert(e2.has<Velocity>());
test_assert(e3.has<Position>());
test_assert(e3.has<Velocity>());
}
void Observer_add_in_yield_existing_multi(void) {
flecs::world world;
flecs::entity e1 = world.entity().set<Position>({}).set<Mass>({});
flecs::entity e2 = world.entity().set<Position>({}).set<Mass>({});
flecs::entity e3 = world.entity().set<Position>({}).set<Mass>({});
world.observer()
.with<Position>()
.with<Mass>()
.event(flecs::OnAdd)
.yield_existing()
.each([](flecs::entity e) {
e.add<Velocity>();
});
test_assert(e1.has<Position>());
test_assert(e1.has<Mass>());
test_assert(e1.has<Velocity>());
test_assert(e2.has<Position>());
test_assert(e2.has<Mass>());
test_assert(e2.has<Velocity>());
test_assert(e3.has<Position>());
test_assert(e3.has<Mass>());
test_assert(e3.has<Velocity>());
}
void Observer_name_from_root(void) {
flecs::world ecs;
flecs::entity sys = ecs.observer<Position>("::ns::MySystem")
.event(flecs::OnSet)
.each([](Position& p) { });
test_str(sys.name(), "MySystem");
flecs::entity ns = ecs.entity("::ns");
test_assert(ns == sys.parent());
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,235 @@
#include <cpp_api.h>
void Paths_name(void) {
flecs::world world;
auto e = flecs::entity(world, "foo");
test_str(e.name().c_str(), "foo");
auto e_world = world.lookup("foo");
test_assert(e.id() == e_world.id());
e_world = world.lookup("::foo");
test_assert(e.id() == e_world.id());
}
void Paths_path_depth_1(void) {
flecs::world world;
auto e = flecs::entity(world, "foo::bar");
test_str(e.name().c_str(), "bar");
test_str(e.path().c_str(), "::foo::bar");
auto e_world = world.lookup("bar");
test_assert(0 == e_world.id());
e_world = world.lookup("foo::bar");
test_assert(e.id() == e_world.id());
e_world = world.lookup("::foo::bar");
test_assert(e.id() == e_world.id());
}
void Paths_path_depth_2(void) {
flecs::world world;
auto e = flecs::entity(world, "foo::bar::hello");
test_str(e.name().c_str(), "hello");
test_str(e.path().c_str(), "::foo::bar::hello");
auto e_world = world.lookup("hello");
test_assert(0 == e_world.id());
e_world = world.lookup("foo::bar::hello");
test_assert(e.id() == e_world.id());
e_world = world.lookup("::foo::bar::hello");
test_assert(e.id() == e_world.id());
}
void Paths_entity_lookup_name(void) {
flecs::world world;
auto parent = flecs::entity(world, "foo");
test_str(parent.name().c_str(), "foo");
test_str(parent.path().c_str(), "::foo");
auto e = flecs::entity(world, "foo::bar");
test_str(e.name().c_str(), "bar");
test_str(e.path().c_str(), "::foo::bar");
auto parent_e = parent.lookup("bar");
test_assert(e.id() == parent_e.id());
parent_e = parent.lookup("::foo::bar");
test_assert(e.id() == parent_e.id());
}
void Paths_entity_lookup_depth_1(void) {
flecs::world world;
auto parent = flecs::entity(world, "foo");
test_str(parent.name().c_str(), "foo");
test_str(parent.path().c_str(), "::foo");
auto e = flecs::entity(world, "foo::bar::hello");
test_str(e.name().c_str(), "hello");
test_str(e.path().c_str(), "::foo::bar::hello");
auto parent_e = parent.lookup("bar::hello");
test_assert(e.id() == parent_e.id());
parent_e = parent.lookup("::foo::bar::hello");
test_assert(e.id() == parent_e.id());
}
void Paths_entity_lookup_depth_2(void) {
flecs::world world;
auto parent = flecs::entity(world, "foo");
test_str(parent.name().c_str(), "foo");
test_str(parent.path().c_str(), "::foo");
auto e = flecs::entity(world, "foo::bar::hello::world");
test_str(e.name().c_str(), "world");
test_str(e.path().c_str(), "::foo::bar::hello::world");
auto parent_e = parent.lookup("bar::hello::world");
test_assert(e.id() == parent_e.id());
parent_e = parent.lookup("::foo::bar::hello::world");
test_assert(e.id() == parent_e.id());
}
void Paths_entity_lookup_from_0(void) {
install_test_abort();
flecs::world world;
flecs::entity foo = world.entity("foo");
test_assert(world.lookup("foo") == foo);
flecs::entity dummy;
test_expect_abort();
dummy.lookup("foo");
}
void Paths_entity_lookup_from_0_w_world(void) {
install_test_abort();
flecs::world world;
flecs::entity foo = world.entity("foo");
test_assert(world.lookup("foo") == foo);
flecs::entity dummy = world.entity(0);
test_expect_abort();
dummy.lookup("foo");
}
void Paths_alias_component(void) {
flecs::world ecs;
auto e = ecs.use<Position>("MyPosition");
auto a = ecs.lookup("MyPosition");
auto c = ecs.lookup("Position");
test_assert(e.id() == a.id());
test_assert(e.id() == c.id());
}
namespace test {
struct Foo {
float x;
float y;
};
}
void Paths_alias_scoped_component(void) {
flecs::world ecs;
auto e = ecs.use<test::Foo>();
auto a = ecs.lookup("Foo");
auto c = ecs.lookup("test::Foo");
test_assert(e.id() == a.id());
test_assert(e.id() == c.id());
}
void Paths_alias_scoped_component_w_name(void) {
flecs::world ecs;
auto e = ecs.use<test::Foo>("FooAlias");
auto a = ecs.lookup("FooAlias");
auto f = ecs.lookup("Foo");
auto c = ecs.lookup("test::Foo");
test_assert(e.id() == a.id());
test_assert(e.id() == c.id());
test_assert(f.id() == 0);
}
void Paths_alias_entity(void) {
flecs::world ecs;
auto e = ecs.entity("Foo");
ecs.use(e, "FooAlias");
auto a = ecs.lookup("FooAlias");
test_assert(e.id() == a.id());
}
void Paths_alias_entity_by_name(void) {
flecs::world ecs;
auto e = ecs.entity("Foo");
ecs.use(e, "FooAlias");
auto l = ecs.lookup("FooAlias");
test_assert(e.id() == l.id());
}
void Paths_alias_entity_by_scoped_name(void) {
flecs::world ecs;
auto e = ecs.entity("Foo::Bar");
auto a = ecs.use("Foo::Bar", "FooAlias");
auto l = ecs.lookup("FooAlias");
test_assert(e.id() == a.id());
test_assert(e.id() == l.id());
}
void Paths_alias_entity_empty(void) {
flecs::world ecs;
auto parent = ecs.entity("parent");
auto child = ecs.entity("child").child_of(parent);
auto e = ecs.lookup("child");
test_assert(e.id() == 0);
ecs.use(child); // alias being nullptr
e = ecs.lookup("child");
test_assert(e.id() != 0);
ecs.use(child, "FooAlias");
e = ecs.lookup("child");
test_assert(e.id() == 0);
e = ecs.lookup("FooAlias");
test_assert(e.id() != 0);
}

View File

@@ -0,0 +1,31 @@
#include <cpp_api.h>
#include <iostream>
// Helper to debug differences in function name strings across compilers
enum Color {
Red, Green, Blue
};
template <typename T>
static size_t pretty_type() {
std::cout << ECS_FUNC_NAME << std::endl;
return 0;
}
template <typename E, E C>
static size_t pretty_enum() {
std::cout << ECS_FUNC_NAME << std::endl;
return 0;
}
void PrettyFunction_component(void) {
pretty_type<Position>();
test_assert(true);
}
void PrettyFunction_enum(void) {
pretty_enum<Color, Color::Red>();
pretty_enum<Color, (Color)3>();
test_assert(true);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,147 @@
#include <cpp_api.h>
void Refs_get_ref_by_ptr(void) {
flecs::world world;
auto e = flecs::entity(world)
.set<Position>({10, 20});
auto ref = e.get_ref<Position>();
test_assert(ref->x == 10);
test_assert(ref->y == 20);
}
void Refs_get_ref_by_method(void) {
flecs::world world;
auto e = flecs::entity(world)
.set<Position>({10, 20});
auto ref = e.get_ref<Position>();
test_assert(ref.get()->x == 10);
test_assert(ref.get()->y == 20);
}
void Refs_ref_after_add(void) {
flecs::world world;
auto e = flecs::entity(world)
.set<Position>({10, 20});
auto ref = e.get_ref<Position>();
e.add<Velocity>();
test_assert(ref->x == 10);
test_assert(ref->y == 20);
}
void Refs_ref_after_remove(void) {
flecs::world world;
auto e = flecs::entity(world)
.set<Position>({10, 20})
.set<Velocity>({1, 1});
auto ref = e.get_ref<Position>();
e.remove<Velocity>();
test_assert(ref->x == 10);
test_assert(ref->y == 20);
}
void Refs_ref_after_set(void) {
flecs::world world;
auto e = flecs::entity(world)
.set<Position>({10, 20});
auto ref = e.get_ref<Position>();
e.set<Velocity>({1, 1});
test_assert(ref->x == 10);
test_assert(ref->y == 20);
}
void Refs_ref_before_set(void) {
flecs::world world;
auto e = flecs::entity(world);
auto ref = e.get_ref<Position>();
e.set<Position>({10, 20});
test_assert(ref->x == 10);
test_assert(ref->y == 20);
}
void Refs_non_const_ref(void) {
flecs::world world;
auto e = world.entity().set<Position>({10, 20});
auto ref = e.get_ref<Position>();
ref->x ++;
test_int(e.get<Position>()->x, 11);
}
void Refs_pair_ref(void) {
flecs::world world;
auto e = world.entity().set<Position, Tag>({10, 20});
auto ref = e.get_ref<Position, Tag>();
ref->x ++;
test_int((e.get<Position, Tag>()->x), 11);
}
void Refs_pair_ref_w_entity(void) {
flecs::world world;
auto tag = world.entity();
auto e = world.entity().set<Position>(tag, {10, 20});
auto ref = e.get_ref<Position>(tag);
ref->x ++;
test_int(e.get<Position>(tag)->x, 11);
}
void Refs_pair_ref_second(void) {
flecs::world world;
auto tag = world.entity();
auto e = world.entity().set_second<Position>(tag, {10, 20});
auto ref = e.get_ref_second<Position>(tag);
ref->x ++;
test_int(e.get_second<Position>(tag)->x, 11);
}
void Refs_from_stage(void) {
flecs::world world;
flecs::world stage = world.get_stage(0); // get default stage
flecs::entity e = stage.entity().set<Position>({10, 20});
auto ref = e.get_ref<Position>();
test_int(ref->x, 10);
test_int(ref->y, 20);
}
void Refs_default_ctor(void) {
flecs::world world;
// Make sure default ctor works
flecs::ref<Position> p;
flecs::entity e = world.entity().set<Position>({10, 20});
p = e.get_ref<Position>();
test_int(p->x, 10);
test_int(p->y, 20);
}
void Refs_try_get(void) {
flecs::world world;
flecs::ref<Position> p;
test_assert(p.try_get() == nullptr);
}

View File

@@ -0,0 +1,869 @@
#include <cpp_api.h>
void RuleBuilder_1_type(void) {
flecs::world ecs;
auto e1 = ecs.entity()
.set<Position>({10, 20});
ecs.entity().set<Velocity>({10, 20});
auto r = ecs.rule<Position>();
int count = 0;
r.each([&](flecs::entity e, Position& p) {
count ++;
test_assert(e == e1);
test_int(p.x, 10);
test_int(p.y, 20);
});
test_int(count, 1);
r.destruct();
}
void RuleBuilder_2_types(void) {
flecs::world ecs;
auto e1 = ecs.entity()
.set<Position>({10, 20})
.set<Velocity>({1, 2});
ecs.entity().set<Velocity>({10, 20});
auto r = ecs.rule<Position, const Velocity>();
int count = 0;
r.each([&](flecs::entity e, Position& p, const Velocity& v) {
count ++;
test_assert(e == e1);
test_int(p.x, 10);
test_int(p.y, 20);
test_int(v.x, 1);
test_int(v.y, 2);
});
test_int(count, 1);
r.destruct();
}
void RuleBuilder_id_term(void) {
flecs::world ecs;
auto Tag = ecs.entity();
auto e1 = ecs.entity()
.add(Tag);
ecs.entity().set<Velocity>({10, 20});
auto r = ecs.rule_builder()
.term(Tag)
.build();
int count = 0;
r.each([&](flecs::entity e) {
count ++;
test_assert(e == e1);
});
test_int(count, 1);
r.destruct();
}
void RuleBuilder_type_term(void) {
flecs::world ecs;
auto e1 = ecs.entity()
.set<Position>({10, 20});
ecs.entity().set<Velocity>({10, 20});
auto r = ecs.rule_builder()
.term<Position>()
.build();
int count = 0;
r.each([&](flecs::entity e) {
count ++;
test_assert(e == e1);
});
test_int(count, 1);
r.destruct();
}
void RuleBuilder_id_pair_term(void) {
flecs::world ecs;
auto Likes = ecs.entity();
auto Apples = ecs.entity();
auto Pears = ecs.entity();
auto e1 = ecs.entity()
.add(Likes, Apples);
ecs.entity()
.add(Likes, Pears);
auto r = ecs.rule_builder()
.term(Likes, Apples)
.build();
int count = 0;
r.each([&](flecs::entity e) {
count ++;
test_assert(e == e1);
});
test_int(count, 1);
r.destruct();
}
void RuleBuilder_id_pair_wildcard_term(void) {
flecs::world ecs;
auto Likes = ecs.entity();
auto Apples = ecs.entity();
auto Pears = ecs.entity();
auto e1 = ecs.entity()
.add(Likes, Apples);
auto e2 = ecs.entity()
.add(Likes, Pears);
auto r = ecs.rule_builder()
.term(Likes, flecs::Wildcard)
.build();
int count = 0;
r.each([&](flecs::iter& it, size_t index) {
if (it.entity(index) == e1) {
test_assert(it.id(1) == ecs.pair(Likes, Apples));
count ++;
}
if (it.entity(index) == e2) {
test_assert(it.id(1) == ecs.pair(Likes, Pears));
count ++;
}
});
test_int(count, 2);
r.destruct();
}
void RuleBuilder_type_pair_term(void) {
flecs::world ecs;
struct Likes { };
struct Apples { };
struct Pears { };
auto e1 = ecs.entity()
.add<Likes, Apples>();
auto e2 = ecs.entity()
.add<Likes, Pears>();
auto r = ecs.rule_builder()
.term<Likes>(flecs::Wildcard)
.build();
int count = 0;
r.each([&](flecs::iter& it, size_t index) {
if (it.entity(index) == e1) {
test_assert((it.id(1) == ecs.pair<Likes, Apples>()));
count ++;
}
if (it.entity(index) == e2) {
test_assert((it.id(1) == ecs.pair<Likes, Pears>()));
count ++;
}
});
test_int(count, 2);
r.destruct();
}
void RuleBuilder_pair_term_w_var(void) {
flecs::world ecs;
struct Likes { };
struct Apples { };
struct Pears { };
auto e1 = ecs.entity()
.add<Likes, Apples>();
auto e2 = ecs.entity()
.add<Likes, Pears>();
auto r = ecs.rule_builder()
.term<Likes>().second().var("Food")
.build();
int food_var = r.find_var("Food");
int count = 0;
r.each([&](flecs::iter& it, size_t index) {
if (it.entity(index) == e1) {
test_assert((it.id(1) == ecs.pair<Likes, Apples>()));
test_assert(it.get_var("Food") == ecs.id<Apples>());
test_assert(it.get_var(food_var) == ecs.id<Apples>());
count ++;
}
if (it.entity(index) == e2) {
test_assert((it.id(1) == ecs.pair<Likes, Pears>()));
test_assert(it.get_var("Food") == ecs.id<Pears>());
test_assert(it.get_var(food_var) == ecs.id<Pears>());
count ++;
}
});
test_int(count, 2);
r.destruct();
}
void RuleBuilder_2_pair_terms_w_var(void) {
flecs::world ecs;
struct Likes { };
struct Eats { };
struct Apples { };
struct Pears { };
auto Bob = ecs.entity()
.add<Eats, Apples>();
auto Alice = ecs.entity()
.add<Eats, Pears>()
.add<Likes>(Bob);
Bob.add<Likes>(Alice);
auto r = ecs.rule_builder()
.term<Eats>().second().var("Food")
.term<Likes>().second().var("Person")
.build();
int food_var = r.find_var("Food");
int person_var = r.find_var("Person");
int count = 0;
r.each([&](flecs::iter& it, size_t index) {
if (it.entity(index) == Bob) {
test_assert((it.id(1) == ecs.pair<Eats, Apples>()));
test_assert(it.get_var("Food") == ecs.id<Apples>());
test_assert(it.get_var(food_var) == ecs.id<Apples>());
test_assert((it.id(2) == ecs.pair<Likes>(Alice)));
test_assert(it.get_var("Person") == Alice);
test_assert(it.get_var(person_var) == Alice);
count ++;
}
if (it.entity(index) == Alice) {
test_assert((it.id(1) == ecs.pair<Eats, Pears>()));
test_assert(it.get_var("Food") == ecs.id<Pears>());
test_assert(it.get_var(food_var) == ecs.id<Pears>());
test_assert((it.id(2) == ecs.pair<Likes>(Bob)));
test_assert(it.get_var("Person") == Bob);
test_assert(it.get_var(person_var) == Bob);
count ++;
}
});
test_int(count, 2);
r.destruct();
}
void RuleBuilder_set_var(void) {
flecs::world ecs;
struct Likes { };
auto Apples = ecs.entity();
auto Pears = ecs.entity();
ecs.entity()
.add<Likes>(Apples);
auto e2 = ecs.entity()
.add<Likes>(Pears);
auto r = ecs.rule_builder()
.term<Likes>().second().var("Food")
.build();
int food_var = r.find_var("Food");
int count = 0;
r.iter()
.set_var(food_var, Pears)
.each([&](flecs::iter& it, size_t index) {
test_assert(it.entity(index) == e2);
test_assert((it.id(1) == ecs.pair<Likes>(Pears)));
test_assert(it.get_var("Food") == Pears);
test_assert(it.get_var(food_var) == Pears);
count ++;
});
test_int(count, 1);
r.destruct();
}
void RuleBuilder_set_2_vars(void) {
flecs::world ecs;
struct Likes { };
struct Eats { };
auto Apples = ecs.entity();
auto Pears = ecs.entity();
auto Bob = ecs.entity()
.add<Eats>(Apples);
auto Alice = ecs.entity()
.add<Eats>(Pears)
.add<Likes>(Bob);
Bob.add<Likes>(Alice);
auto r = ecs.rule_builder()
.term<Eats>().second().var("Food")
.term<Likes>().second().var("Person")
.build();
int food_var = r.find_var("Food");
int person_var = r.find_var("Person");
int count = 0;
r.iter()
.set_var(food_var, Pears)
.set_var(person_var, Bob)
.each([&](flecs::iter& it, size_t index) {
test_assert(it.entity(index) == Alice);
test_assert((it.id(1) == ecs.pair<Eats>(Pears)));
test_assert((it.id(2) == ecs.pair<Likes>(Bob)));
test_assert(it.get_var("Food") == Pears);
test_assert(it.get_var(food_var) == Pears);
test_assert(it.get_var("Person") == Bob);
test_assert(it.get_var(person_var) == Bob);
count ++;
});
test_int(count, 1);
r.destruct();
}
void RuleBuilder_set_var_by_name(void) {
flecs::world ecs;
struct Likes { };
auto Apples = ecs.entity();
auto Pears = ecs.entity();
ecs.entity()
.add<Likes>(Apples);
auto e2 = ecs.entity()
.add<Likes>(Pears);
auto r = ecs.rule_builder()
.term<Likes>().second().var("Food")
.build();
int count = 0;
r.iter()
.set_var("Food", Pears)
.each([&](flecs::iter& it, size_t index) {
test_assert(it.entity(index) == e2);
test_assert((it.id(1) == ecs.pair<Likes>(Pears)));
count ++;
});
test_int(count, 1);
r.destruct();
}
void RuleBuilder_set_2_vars_by_name(void) {
flecs::world ecs;
struct Likes { };
struct Eats { };
auto Apples = ecs.entity();
auto Pears = ecs.entity();
auto Bob = ecs.entity()
.add<Eats>(Apples);
auto Alice = ecs.entity()
.add<Eats>(Pears)
.add<Likes>(Bob);
Bob.add<Likes>(Alice);
auto r = ecs.rule_builder()
.term<Eats>().second().var("Food")
.term<Likes>().second().var("Person")
.build();
int food_var = r.find_var("Food");
int person_var = r.find_var("Person");
int count = 0;
r.iter()
.set_var("Food", Pears)
.set_var("Person", Bob)
.each([&](flecs::iter& it, size_t index) {
test_assert(it.entity(index) == Alice);
test_assert((it.id(1) == ecs.pair<Eats>(Pears)));
test_assert((it.id(2) == ecs.pair<Likes>(Bob)));
test_assert(it.get_var("Food") == Pears);
test_assert(it.get_var(food_var) == Pears);
test_assert(it.get_var("Person") == Bob);
test_assert(it.get_var(person_var) == Bob);
count ++;
});
test_int(count, 1);
r.destruct();
}
void RuleBuilder_expr_w_var(void) {
flecs::world ecs;
auto rel = ecs.entity("Rel");
auto obj = ecs.entity();
auto e = ecs.entity().add(rel, obj);
auto r = ecs.rule_builder()
.expr("(Rel, $X)")
.build();
int x_var = r.find_var("X");
test_assert(x_var != -1);
int32_t count = 0;
r.each([&](flecs::iter& it, size_t index) {
test_assert(it.entity(index) == e);
test_assert(it.pair(1).second() == obj);
count ++;
});
test_int(count, 1);
r.destruct();
}
void RuleBuilder_get_first(void) {
flecs::world ecs;
struct A {};
auto e1 = ecs.entity().add<A>();
ecs.entity().add<A>();
ecs.entity().add<A>();
auto q = ecs.rule<A>();
auto first = q.iter().first();
test_assert(first != 0);
test_assert(first == e1);
q.destruct();
}
void RuleBuilder_get_count_direct(void) {
flecs::world ecs;
struct A {};
ecs.entity().add<A>();
ecs.entity().add<A>();
ecs.entity().add<A>();
auto q = ecs.rule<A>();
test_int(3, q.count());
q.destruct();
}
void RuleBuilder_get_is_true_direct(void) {
flecs::world ecs;
struct A {};
struct B {};
ecs.entity().add<A>();
ecs.entity().add<A>();
ecs.entity().add<A>();
auto q_1 = ecs.rule<A>();
auto q_2 = ecs.rule<B>();
test_bool(true, q_1.is_true());
test_bool(false, q_2.is_true());
q_1.destruct();
q_2.destruct();
}
void RuleBuilder_get_first_direct(void) {
flecs::world ecs;
struct A {};
auto e1 = ecs.entity().add<A>();
ecs.entity().add<A>();
ecs.entity().add<A>();
auto q = ecs.rule<A>();
auto first = q.first();
test_assert(first != 0);
test_assert(first == e1);
q.destruct();
}
void RuleBuilder_var_src_w_prefixed_name(void) {
flecs::world ecs;
struct Foo { };
auto r = ecs.rule_builder()
.term<Foo>().src("$Var")
.build();
auto e = ecs.entity().add<Foo>();
int32_t count = 0;
r.iter([&](flecs::iter& it) {
test_assert(it.get_var("Var") == e);
count ++;
});
test_int(count, 1);
r.destruct();
}
void RuleBuilder_var_first_w_prefixed_name(void) {
flecs::world ecs;
struct Foo { };
auto r = ecs.rule_builder()
.term<Foo>()
.term().first("$Var")
.build();
auto e = ecs.entity().add<Foo>();
int32_t count = 0;
r.iter([&](flecs::iter& it) {
test_int(it.count(), 1);
test_uint(it.entity(0), e);
test_assert(it.get_var("Var") == ecs.id<Foo>());
count ++;
});
test_int(count, 1);
r.destruct();
}
void RuleBuilder_var_second_w_prefixed_name(void) {
flecs::world ecs;
struct Foo { };
auto r = ecs.rule_builder()
.term<Foo>().second("$Var")
.build();
auto t = ecs.entity();
auto e = ecs.entity().add<Foo>(t);
int32_t count = 0;
r.iter([&](flecs::iter& it) {
test_int(it.count(), 1);
test_uint(it.entity(0), e);
test_assert(it.get_var("Var") == t);
count ++;
});
test_int(count, 1);
r.destruct();
}
void RuleBuilder_term_w_second_var_string(void) {
flecs::world ecs;
flecs::entity Foo = ecs.entity();
auto r = ecs.rule_builder()
.term(Foo, "$Var")
.build();
auto t = ecs.entity();
auto e = ecs.entity().add(Foo, t);
int32_t count = 0;
r.iter([&](flecs::iter& it) {
test_int(it.count(), 1);
test_uint(it.entity(0), e);
test_assert(it.get_var("Var") == t);
count ++;
});
test_int(count, 1);
r.destruct();
}
void RuleBuilder_term_type_w_second_var_string(void) {
flecs::world ecs;
struct Foo { };
auto r = ecs.rule_builder()
.term<Foo>("$Var")
.build();
auto t = ecs.entity();
auto e = ecs.entity().add<Foo>(t);
int32_t count = 0;
r.iter([&](flecs::iter& it) {
test_int(it.count(), 1);
test_uint(it.entity(0), e);
test_assert(it.get_var("Var") == t);
count ++;
});
test_int(count, 1);
r.destruct();
}
void RuleBuilder_named_rule(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>();
auto e2 = ecs.entity().add<Position>();
auto q = ecs.rule<Position>("my_query");
int32_t count = 0;
q.each([&](flecs::entity e, Position&) {
test_assert(e == e1 || e == e2);
count ++;
});
test_int(count, 2);
flecs::entity qe = q.entity();
test_assert(qe != 0);
test_str(qe.name(), "my_query");
q.destruct();
}
void RuleBuilder_named_scoped_rule(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>();
auto e2 = ecs.entity().add<Position>();
auto q = ecs.rule<Position>("my::query");
int32_t count = 0;
q.each([&](flecs::entity e, Position&) {
test_assert(e == e1 || e == e2);
count ++;
});
test_int(count, 2);
flecs::entity qe = q.entity();
test_assert(qe != 0);
test_str(qe.name(), "query");
test_str(qe.path(), "::my::query");
q.destruct();
}
void RuleBuilder_is_valid(void) {
flecs::world ecs;
auto q_1 = ecs.rule<Position>();
test_assert(q_1.is_valid());
flecs::log::set_level(-4);
auto q_2 = ecs.rule_builder().expr("foo").build();
test_assert(!q_2.is_valid());
q_1.destruct();
}
void RuleBuilder_unresolved_by_name(void) {
flecs::world ecs;
auto q = ecs.rule_builder()
.filter_flags(EcsFilterUnresolvedByName)
.expr("$this == Foo")
.build();
test_assert(q.is_valid());
test_false(q.iter().is_true());
ecs.entity("Foo");
test_true(q.iter().is_true());
q.destruct();
}
void RuleBuilder_scope(void) {
flecs::world ecs;
flecs::entity Root = ecs.entity();
flecs::entity TagA = ecs.entity();
flecs::entity TagB = ecs.entity();
ecs.entity()
.add(Root)
.add(TagA)
.add(TagB);
auto e2 = ecs.entity()
.add(Root)
.add(TagA);
ecs.entity()
.add(Root)
.add(TagB);
ecs.entity()
.add(Root);
auto r = ecs.rule_builder()
.with(Root)
.scope_open().not_()
.with(TagA)
.without(TagB)
.scope_close()
.build();
int32_t count = 0;
r.each([&](flecs::entity e) {
test_assert(e != e2);
count ++;
});
test_int(count, 3);
r.destruct();
}
void RuleBuilder_iter_w_stage(void) {
flecs::world ecs;
ecs.set_stage_count(2);
flecs::world stage = ecs.get_stage(1);
auto e1 = ecs.entity().add<Position>();
auto q = ecs.rule<Position>();
int32_t count = 0;
q.each(stage, [&](flecs::iter& it, size_t i, Position&) {
test_assert(it.world() == stage);
test_assert(it.entity(i) == e1);
count ++;
});
test_int(count, 1);
q.destruct();
}
void RuleBuilder_inspect_terms_w_expr(void) {
flecs::world ecs;
flecs::rule<> f = ecs.rule_builder()
.expr("(ChildOf,0)")
.build();
int32_t count = 0;
f.each_term([&](flecs::term &term) {
test_assert(term.id().is_pair());
count ++;
});
test_int(count, 1);
f.destruct();
}
void RuleBuilder_find(void) {
flecs::world ecs;
/* auto e1 = */ ecs.entity().set<Position>({10, 20});
auto e2 = ecs.entity().set<Position>({20, 30});
auto q = ecs.rule<Position>();
auto r = q.find([](Position& p) {
return p.x == 20;
});
test_assert(r == e2);
q.destruct();
}
void RuleBuilder_find_not_found(void) {
flecs::world ecs;
/* auto e1 = */ ecs.entity().set<Position>({10, 20});
/* auto e2 = */ ecs.entity().set<Position>({20, 30});
auto q = ecs.rule<Position>();
auto r = q.find([](Position& p) {
return p.x == 30;
});
test_assert(!r);
q.destruct();
}
void RuleBuilder_find_w_entity(void) {
flecs::world ecs;
/* auto e1 = */ ecs.entity().set<Position>({10, 20}).set<Velocity>({20, 30});
auto e2 = ecs.entity().set<Position>({20, 30}).set<Velocity>({20, 30});
auto q = ecs.rule<Position>();
auto r = q.find([](flecs::entity e, Position& p) {
return p.x == e.get<Velocity>()->x &&
p.y == e.get<Velocity>()->y;
});
test_assert(r == e2);
q.destruct();
}

View File

@@ -0,0 +1,318 @@
#include <cpp_api.h>
void Singleton_set_get_singleton(void) {
flecs::world world;
world.set<Position>({10, 20});
const Position *p = world.get<Position>();
test_assert(p != NULL);
test_int(p->x, 10);
test_int(p->y, 20);
}
void Singleton_get_mut_singleton(void) {
flecs::world world;
Position *p_mut = world.get_mut<Position>();
p_mut->x = 10;
p_mut->y = 20;
const Position *p = world.get<Position>();
test_assert(p != NULL);
test_int(p->x, 10);
test_int(p->y, 20);
}
void Singleton_emplace_singleton(void) {
flecs::world world;
world.emplace<Position>(10.0f, 20.0f);
const Position *p = world.get<Position>();
test_assert(p != NULL);
test_int(p->x, 10);
test_int(p->y, 20);
}
void Singleton_modified_singleton(void) {
flecs::world world;
int invoked = 0;
world.observer<Position>()
.event(flecs::OnSet)
.iter([&](flecs::iter it, Position *p) {
invoked ++;
});
auto e = world.entity();
Position *p = e.get_mut<Position>();
test_assert(p != NULL);
test_int(invoked, 0);
e.modified<Position>();
test_int(invoked, 1);
}
void Singleton_add_singleton(void) {
flecs::world world;
int invoked = 0;
world.observer<Position>()
.event(flecs::OnAdd)
.iter([&](flecs::iter it, Position *p) {
invoked ++;
});
world.add<Position>();
test_int(invoked, 1);
}
void Singleton_remove_singleton(void) {
flecs::world world;
int invoked = 0;
world.observer<Position>()
.event(flecs::OnRemove)
.iter([&](flecs::iter it, Position *p) {
invoked ++;
});
Position *p_mut = world.get_mut<Position>();
test_assert(p_mut != NULL);
world.remove<Position>();
test_int(invoked, 1);
}
void Singleton_has_singleton(void) {
flecs::world world;
test_assert(!world.has<Position>());
world.set<Position>({10, 20});
test_assert(world.has<Position>());
}
void Singleton_singleton_system(void) {
flecs::world world;
world.set<Position>({10, 20});
world.system<>()
.expr("[inout] Position($)")
.iter([](flecs::iter it) {
auto p = it.field<Position>(1);
test_int(p->x, 10);
test_int(p->y, 20);
p->x ++;
p->y ++;
});
world.progress();
const Position *p = world.get<Position>();
test_assert(p != NULL);
test_int(p->x, 11);
test_int(p->y, 21);
}
void Singleton_get_singleton(void) {
flecs::world world;
world.set<Position>({10, 20});
auto s = world.singleton<Position>();
test_assert(s.has<Position>());
test_assert(s.id() == flecs::type_id<Position>());
const Position* p = s.get<Position>();
test_int(p->x, 10);
test_int(p->y, 20);
}
void Singleton_type_id_from_world(void) {
flecs::world world;
world.set<Position>({10, 20});
flecs::entity_t id = world.id<Position>();
test_assert(id == flecs::type_id<Position>());
auto s = world.singleton<Position>();
test_assert(s.id() == flecs::type_id<Position>());
test_assert(s.id() == flecs::type_id<Position>());
}
void Singleton_set_lambda(void) {
flecs::world world;
world.set([](Position& p) {
p.x = 10;
p.y = 20;
});
const Position* p = world.get<Position>();
test_int(p->x, 10);
test_int(p->y, 20);
world.set([](Position& p) {
p.x ++;
p.y ++;
});
p = world.get<Position>();
test_int(p->x, 11);
test_int(p->y, 21);
}
void Singleton_get_lambda(void) {
flecs::world world;
world.set<Position>({10, 20});
int32_t count = 0;
world.get([&](const Position& p) {
test_int(p.x, 10);
test_int(p.y, 20);
count ++;
});
test_int(count, 1);
}
void Singleton_get_write_lambda(void) {
flecs::world world;
world.set<Position>({10, 20});
int32_t count = 0;
world.get([&](Position& p) {
test_int(p.x, 10);
test_int(p.y, 20);
p.x ++;
p.y ++;
count ++;
});
test_int(count, 1);
const Position *p = world.get<Position>();
test_int(p->x, 11);
test_int(p->y, 21);
}
void Singleton_get_set_singleton_pair_R_T(void) {
flecs::world world;
world.set<Position, Tag>({10, 20});
const Position *p = world.get<Position, Tag>();
test_assert(p != nullptr);
test_int(p->x, 10);
test_int(p->y, 20);
}
void Singleton_get_set_singleton_pair_R_t(void) {
flecs::world world;
flecs::entity tgt = world.entity();
world.set<Position>(tgt, {10, 20});
const Position *p = world.get<Position>(tgt);
test_assert(p != nullptr);
test_int(p->x, 10);
test_int(p->y, 20);
}
void Singleton_add_remove_singleton_pair_R_T(void) {
flecs::world world;
world.add<Position, Tag>();
test_assert((world.has<Position, Tag>()));
world.remove<Position, Tag>();
test_assert(!(world.has<Position, Tag>()));
}
void Singleton_add_remove_singleton_pair_R_t(void) {
flecs::world world;
flecs::entity tgt = world.entity();
world.add<Position>(tgt);
test_assert((world.has<Position>(tgt)));
world.remove<Position>(tgt);
test_assert(!(world.has<Position>(tgt)));
}
void Singleton_add_remove_singleton_pair_r_t(void) {
flecs::world world;
flecs::entity rel = world.entity();
flecs::entity tgt = world.entity();
world.add(rel, tgt);
test_assert((world.has(rel, tgt)));
world.remove(rel, tgt);
test_assert(!(world.has(rel, tgt)));
}
void Singleton_get_target(void) {
flecs::world world;
auto Rel = world.singleton<Tag>();
auto obj1 = world.entity()
.add<Position>();
auto obj2 = world.entity()
.add<Velocity>();
auto obj3 = world.entity()
.add<Mass>();
flecs::entity entities[3] = {obj1, obj2, obj3};
world.add<Tag>(obj1);
world.add<Tag>(obj2);
world.add(Rel, obj3);
auto p = world.target<Tag>();
test_assert(p != 0);
test_assert(p == obj1);
p = world.target<Tag>(Rel);
test_assert(p != 0);
test_assert(p == obj1);
p = world.target(Rel);
test_assert(p != 0);
test_assert(p == obj1);
for (int i = 0; i < 3; i++) {
p = world.target<Tag>(i);
test_assert(p != 0);
test_assert(p == entities[i]);
}
for (int i = 0; i < 3; i++) {
p = world.target<Tag>(Rel, i);
test_assert(p != 0);
test_assert(p == entities[i]);
}
for (int i = 0; i < 3; i++) {
p = world.target(Rel, i);
test_assert(p != 0);
test_assert(p == entities[i]);
}
}

View File

@@ -0,0 +1,29 @@
#include <cpp_api.h>
void Snapshot_simple_snapshot(void) {
flecs::world world;
auto e = flecs::entity(world)
.set<Position>({10, 20})
.set<Velocity>({1, 1});
flecs::snapshot s(world);
s.take();
e.set<Position>({30, 40});
e.set<Velocity>({2, 2});
s.restore();
const Position *p = e.get<Position>();
const Velocity *v = e.get<Velocity>();
test_assert(p != NULL);
test_assert(v != NULL);
test_int(p->x, 10);
test_int(p->y, 20);
test_int(v->x, 1);
test_int(v->y, 1);
}

View File

@@ -0,0 +1,257 @@
#include <cpp_api.h>
void Switch_add_case(void) {
flecs::world world;
auto Standing = world.entity("Standing");
auto Walking = world.entity("Walking");
auto Movement = world.entity().add(flecs::Union);
auto e = world.entity()
.add(Movement, Standing);
test_assert(e.has(Movement, Standing));
auto table = e.table();
e.add(Movement, Walking);
test_assert(e.table() == table);
test_assert(e.has(Movement, Walking));
test_assert(!e.has(Movement, Standing));
}
void Switch_get_case(void) {
flecs::world world;
auto Standing = world.entity("Standing");
world.entity("Walking");
auto Movement = world.entity().add(flecs::Union);
auto e = world.entity()
.add(Movement, Standing);
test_assert(e.has(Movement, Standing));
test_assert(e.target(Movement) == Standing);
}
void Switch_system_w_case(void) {
flecs::world world;
auto Standing = world.entity("Standing");
auto Walking = world.entity("Walking");
auto Movement = world.entity("Movement").add(flecs::Union);
world.entity().add(Movement, Walking);
world.entity().add(Movement, Walking);
world.entity().add(Movement, Standing);
int count = 0, invoke_count = 0;
world.system()
.expr("(Movement, Walking)")
.iter([&](flecs::iter it) {
auto movement = it.field<flecs::entity_t>(1);
invoke_count ++;
for (auto i : it) {
test_assert(movement[i] == Walking.id());
count ++;
}
});
world.progress();
test_int(invoke_count, 2);
test_int(count, 2);
}
void Switch_system_w_case_builder(void) {
flecs::world world;
auto Standing = world.entity("Standing");
auto Walking = world.entity("Walking");
auto Movement = world.entity().add(flecs::Union);
world.entity().add(Movement, Walking);
world.entity().add(Movement, Walking);
world.entity().add(Movement, Standing);
int count = 0, invoke_count = 0;
world.system()
.term(Movement, Walking)
.iter([&](flecs::iter it) {
auto movement = it.field<flecs::entity_t>(1);
invoke_count ++;
for (auto i : it) {
test_assert(movement[i] == Walking.id());
count ++;
}
});
world.progress();
test_int(invoke_count, 2);
test_int(count, 2);
}
void Switch_system_w_switch(void) {
flecs::world world;
auto Standing = world.entity("Standing");
auto Walking = world.entity("Walking");
auto Movement = world.entity("Movement").add(flecs::Union);
auto e1 = world.entity().add(Movement, Walking);
auto e2 = world.entity().add(Movement, Walking);
auto e3 = world.entity().add(Movement, Standing);
int count = 0, invoke_count = 0;
world.system()
.expr("(Movement, *)")
.iter([&](flecs::iter it) {
flecs::column<flecs::entity_t> movement(it, 1);
invoke_count ++;
for (auto i : it) {
if (it.entity(i) == e1 || it.entity(i) == e2) {
test_int(movement[i], Walking.id());
} else if (it.entity(i) == e3) {
test_int(movement[i], Standing.id());
}
count ++;
}
});
world.progress();
test_int(invoke_count, 1);
test_int(count, 3);
}
struct Movement { };
struct Standing { };
struct Walking { };
void Switch_system_w_sw_type_builder(void) {
flecs::world world;
world.component<Movement>().add(flecs::Union);
world.entity().add<Movement, Walking>();
world.entity().add<Movement, Walking>();
world.entity().add<Movement, Standing>();
int count = 0, invoke_count = 0;
world.system<>()
.term<Movement, Walking>()
.iter([&](flecs::iter it) {
auto movement = it.field<flecs::entity_t>(1);
invoke_count ++;
for (auto i : it) {
test_assert(movement[i] == world.id<Walking>());
count ++;
}
});
world.progress();
test_int(invoke_count, 2);
test_int(count, 2);
}
void Switch_add_case_w_type(void) {
flecs::world world;
world.component<Movement>().add(flecs::Union);
auto e = world.entity().add<Movement, Standing>();
test_assert((e.has<Movement, Standing>()));
e.add<Movement, Walking>();
test_assert((e.has<Movement, Walking>()));
test_assert((!e.has<Movement, Standing>()));
}
void Switch_add_switch_w_type(void) {
flecs::world world;
world.component<Movement>().add(flecs::Union);
auto e = world.entity().add<Movement, Standing>();
test_assert((e.has<Movement, Standing>()));
e.add<Movement, Walking>();
test_assert((e.has<Movement, Walking>()));
test_assert((!e.has<Movement, Standing>()));
}
void Switch_add_remove_switch_w_type(void) {
flecs::world world;
world.component<Movement>().add(flecs::Union);
auto e = world.entity().add<Movement, Standing>();
test_assert(e.has<Movement>(flecs::Wildcard));
test_assert((e.has<Movement, Standing>()));
auto table = e.table();
e.add<Movement, Walking>();
test_assert((e.has<Movement, Walking>()));
test_assert((!e.has<Movement, Standing>()));
test_assert(e.table() == table);
auto c = e.target<Movement>();
test_assert(c != 0);
test_assert(c == world.id<Walking>());
e.remove<Movement>(flecs::Wildcard);
test_assert(!e.has<Movement>(flecs::Wildcard));
test_assert((!e.has<Movement, Walking>()));
test_assert(e.table() != table);
}
enum Color {
Red,
Green,
Blue
};
void Switch_switch_enum_type(void) {
flecs::world world;
world.component<Color>().add(flecs::Union);
auto e = world.entity().add(Red);
test_assert(e.has(Red));
test_assert(!e.has(Green));
test_assert(!e.has(Blue));
test_assert(e.has<Color>(flecs::Wildcard));
auto table = e.table();
e.add(Green);
test_assert(!e.has(Red));
test_assert(e.has(Green));
test_assert(!e.has(Blue));
test_assert(e.has<Color>(flecs::Wildcard));
test_assert(e.table() == table);
e.add(Blue);
test_assert(!e.has(Red));
test_assert(!e.has(Green));
test_assert(e.has(Blue));
test_assert(e.has<Color>(flecs::Wildcard));
test_assert(e.table() == table);
e.remove<Color>();
test_assert(!e.has(Red));
test_assert(!e.has(Green));
test_assert(!e.has(Blue));
test_assert(!e.has<Color>(flecs::Wildcard));
test_assert(e.table() != table);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,528 @@
#include <cpp_api.h>
void SystemBuilder_builder_assign_same_type(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>().add<Velocity>();
ecs.entity().add<Position>();
int32_t count = 0;
flecs::system s =
ecs.system<Position, Velocity>()
.each([&](flecs::entity e, Position& p, Velocity& v) {
count ++;
test_assert(e == e1);
});
test_int(count, 0);
s.run();
test_int(count, 1);
}
void SystemBuilder_builder_build_to_auto(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>().add<Velocity>();
ecs.entity().add<Position>();
int32_t count = 0;
auto s = ecs.system<Position, Velocity>()
.each([&](flecs::entity e, Position& p, Velocity& v) {
count ++;
test_assert(e == e1);
});
test_int(count, 0);
s.run();
test_int(count, 1);
}
void SystemBuilder_builder_build_n_statements(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>().add<Velocity>();
ecs.entity().add<Position>();
int32_t count = 0;
auto qb = ecs.system<>();
qb.term<Position>();
qb.term<Velocity>();
auto s = qb.each([&](flecs::entity e) {
count ++;
test_assert(e == e1);
});
s.run();
test_int(count, 1);
}
void SystemBuilder_1_type(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>();
ecs.entity().add<Velocity>();
int32_t count = 0;
auto s = ecs.system<Position>()
.each([&](flecs::entity e, Position& p) {
count ++;
test_assert(e == e1);
});
test_int(count, 0);
s.run();
test_int(count, 1);
}
void SystemBuilder_add_1_type(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>();
ecs.entity().add<Velocity>();
int32_t count = 0;
auto s = ecs.system<>()
.term<Position>()
.each([&](flecs::entity e) {
count ++;
test_assert(e == e1);
});
test_int(count, 0);
s.run();
test_int(count, 1);
}
void SystemBuilder_add_2_types(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>().add<Velocity>();
ecs.entity().add<Velocity>();
int32_t count = 0;
auto s = ecs.system<>()
.term<Position>()
.term<Velocity>()
.each([&](flecs::entity e) {
count ++;
test_assert(e == e1);
});
test_int(count, 0);
s.run();
test_int(count, 1);
}
void SystemBuilder_add_1_type_w_1_type(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>().add<Velocity>();
ecs.entity().add<Velocity>();
int32_t count = 0;
auto s = ecs.system<Position>()
.term<Velocity>()
.each([&](flecs::entity e, Position& p) {
count ++;
test_assert(e == e1);
});
test_int(count, 0);
s.run();
test_int(count, 1);
}
void SystemBuilder_add_2_types_w_1_type(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>().add<Velocity>().add<Mass>();
ecs.entity().add<Velocity>();
int32_t count = 0;
auto s = ecs.system<Position>()
.term<Velocity>()
.term<Mass>()
.each([&](flecs::entity e, Position& p) {
count ++;
test_assert(e == e1);
});
test_int(count, 0);
s.run();
test_int(count, 1);
}
void SystemBuilder_add_pair(void) {
flecs::world ecs;
auto Likes = ecs.entity();
auto Bob = ecs.entity();
auto Alice = ecs.entity();
auto e1 = ecs.entity().add(Likes, Bob);
ecs.entity().add(Likes, Alice);
int32_t count = 0;
auto s = ecs.system<>()
.term(Likes, Bob)
.each([&](flecs::entity e) {
count ++;
test_assert(e == e1);
});
test_int(count, 0);
s.run();
test_int(count, 1);
}
void SystemBuilder_add_not(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>();
ecs.entity().add<Position>().add<Velocity>();
int32_t count = 0;
auto s = ecs.system<Position>()
.term<Velocity>().oper(flecs::Not)
.each([&](flecs::entity e, Position& p) {
count ++;
test_assert(e == e1);
});
test_int(count, 0);
s.run();
test_int(count, 1);
}
void SystemBuilder_add_or(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>();
auto e2 = ecs.entity().add<Velocity>();
ecs.entity().add<Mass>();
int32_t count = 0;
auto s = ecs.system<>()
.term<Position>().oper(flecs::Or)
.term<Velocity>()
.each([&](flecs::entity e) {
count ++;
test_assert(e == e1 || e == e2);
});
test_int(count, 0);
s.run();
test_int(count, 2);
}
void SystemBuilder_add_optional(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>();
auto e2 = ecs.entity().add<Position>().add<Velocity>();
ecs.entity().add<Velocity>().add<Mass>();
int32_t count = 0;
auto s = ecs.system<>()
.term<Position>()
.term<Velocity>().oper(flecs::Optional)
.each([&](flecs::entity e) {
count ++;
test_assert(e == e1 || e == e2);
});
test_int(count, 0);
s.run();
test_int(count, 2);
}
void SystemBuilder_ptr_type(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>();
auto e2 = ecs.entity().add<Position>().add<Velocity>();
ecs.entity().add<Velocity>().add<Mass>();
int32_t count = 0;
auto s = ecs.system<Position, Velocity*>()
.each([&](flecs::entity e, Position& p, Velocity* v) {
count ++;
test_assert(e == e1 || e == e2);
});
test_int(count, 0);
s.run();
test_int(count, 2);
}
void SystemBuilder_const_type(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>();
ecs.entity().add<Velocity>();
int32_t count = 0;
auto s = ecs.system<const Position>()
.each([&](flecs::entity e, const Position& p) {
count ++;
test_assert(e == e1);
});
test_int(count, 0);
s.run();
test_int(count, 1);
}
void SystemBuilder_string_term(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>();
ecs.entity().add<Velocity>();
int32_t count = 0;
auto s = ecs.system<>()
.expr("Position")
.each([&](flecs::entity e) {
count ++;
test_assert(e == e1);
});
s.run();
test_int(count, 1);
}
void SystemBuilder_singleton_term(void) {
flecs::world ecs;
struct Entity {
flecs::entity_view value;
};
struct Singleton {
int32_t value;
};
ecs.set<Singleton>({10});
int32_t count = 0;
auto s = ecs.system<Entity>()
.term<Singleton>().singleton()
.iter([&](flecs::iter& it, Entity *e) {
auto s = it.field<const Singleton>(2);
test_assert(!it.is_self(2));
test_int(s->value, 10);
const Singleton& s_ref = *s;
test_int(s_ref.value, 10);
for (auto i : it) {
test_assert(it.entity(i) == e[i].value);
count ++;
}
});
auto
e = ecs.entity(); e.set<Entity>({e});
e = ecs.entity(); e.set<Entity>({e});
e = ecs.entity(); e.set<Entity>({e});
s.run();
test_int(count, 3);
}
void SystemBuilder_10_terms(void) {
flecs::world ecs;
int count = 0;
auto e = ecs.entity()
.add<TagA>()
.add<TagB>()
.add<TagC>()
.add<TagD>()
.add<TagE>()
.add<TagF>()
.add<TagG>()
.add<TagH>()
.add<TagI>()
.add<TagJ>();
auto s = ecs.system<>()
.term<TagA>()
.term<TagB>()
.term<TagC>()
.term<TagD>()
.term<TagE>()
.term<TagF>()
.term<TagG>()
.term<TagH>()
.term<TagI>()
.term<TagJ>()
.iter([&](flecs::iter& it) {
test_int(it.count(), 1);
test_assert(it.entity(0) == e);
test_int(it.field_count(), 10);
count ++;
});
s.run();
test_int(count, 1);
}
void SystemBuilder_20_terms(void) {
flecs::world ecs;
int count = 0;
auto e = ecs.entity()
.add<TagA>()
.add<TagB>()
.add<TagC>()
.add<TagD>()
.add<TagE>()
.add<TagF>()
.add<TagG>()
.add<TagH>()
.add<TagI>()
.add<TagJ>()
.add<TagK>()
.add<TagL>()
.add<TagM>()
.add<TagN>()
.add<TagO>()
.add<TagP>()
.add<TagQ>()
.add<TagR>()
.add<TagS>()
.add<TagT>();
auto s = ecs.system<>()
.term<TagA>()
.term<TagB>()
.term<TagC>()
.term<TagD>()
.term<TagE>()
.term<TagF>()
.term<TagG>()
.term<TagH>()
.term<TagI>()
.term<TagJ>()
.term<TagK>()
.term<TagL>()
.term<TagM>()
.term<TagN>()
.term<TagO>()
.term<TagP>()
.term<TagQ>()
.term<TagR>()
.term<TagS>()
.term<TagT>()
.iter([&](flecs::iter& it) {
test_int(it.count(), 1);
test_assert(it.entity(0) == e);
test_int(it.field_count(), 20);
count ++;
});
s.run();
test_int(count, 1);
}
void SystemBuilder_name_arg(void) {
flecs::world ecs;
auto s = ecs.system<const Position>("MySystem")
.arg(1).src().name("MySystem")
.iter([](flecs::iter& Iter, const Position* Config)
{ });
test_assert(s.has<Position>());
}
void SystemBuilder_create_w_no_template_args(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>();
int32_t count = 0;
auto s = ecs.system()
.term<Position>()
.each([&](flecs::entity e) {
count ++;
test_assert(e == e1);
});
test_int(count, 0);
s.run();
test_int(count, 1);
}
void SystemBuilder_write_annotation(void) {
flecs::world ecs;
struct TagA { };
struct TagB { };
auto e1 = ecs.entity().add<TagA>();
int32_t a_count = 0, b_count = 0;
ecs.system<TagA>()
.term<TagB>().write()
.each([&](flecs::entity e, TagA) {
a_count ++;
test_assert(e == e1);
e.add<TagB>();
});
ecs.system<TagB>()
.each([&](flecs::entity e, TagB) {
b_count ++;
test_assert(e == e1);
test_assert(e.has<TagB>());
});
test_int(a_count, 0);
test_int(b_count, 0);
ecs.progress();
test_int(a_count, 1);
test_int(b_count, 1);
test_assert(e1.has<TagB>());
}
void SystemBuilder_name_from_root(void) {
flecs::world ecs;
flecs::entity sys = ecs.system("::ns::MySystem")
.each([](flecs::entity e) { });
test_str(sys.name(), "MySystem");
flecs::entity ns = ecs.entity("::ns");
test_assert(ns == sys.parent());
}

View File

@@ -0,0 +1,684 @@
#include <cpp_api.h>
void Table_each(void) {
flecs::world ecs;
ecs.entity().add<Position>();
auto e2 = ecs.entity().add<Velocity>();
ecs.filter<Position>()
.each([&](flecs::entity e, Position& p) {
e2.add<Mass>();
});
test_assert(e2.has<Mass>());
}
void Table_each_locked(void) {
install_test_abort();
flecs::world ecs;
auto e1 = ecs.entity().add<Position>();
ecs.filter<Position>()
.each([&](flecs::entity e, Position& p) {
test_expect_abort();
e1.add<Mass>();
});
test_assert(false);
}
void Table_each_without_entity(void) {
flecs::world ecs;
ecs.entity().add<Position>();
auto e2 = ecs.entity().add<Velocity>();
ecs.filter<Position>()
.each([&](Position& p) {
e2.add<Mass>();
});
test_assert(e2.has<Mass>());
}
void Table_each_without_entity_locked(void) {
install_test_abort();
flecs::world ecs;
auto e1 = ecs.entity().add<Position>();
ecs.filter<Position>()
.each([&](Position& p) {
test_expect_abort();
e1.add<Mass>();
});
test_assert(false);
}
void Table_iter(void) {
flecs::world ecs;
ecs.entity().add<Position>();
auto e2 = ecs.entity().add<Velocity>();
ecs.filter<Position>()
.iter([&](flecs::iter& it, Position* p) {
e2.add<Mass>();
});
test_assert(e2.has<Mass>());
}
void Table_iter_locked(void) {
install_test_abort();
flecs::world ecs;
auto e1 = ecs.entity().add<Position>();
ecs.filter<Position>()
.iter([&](flecs::iter& it, Position* p) {
test_expect_abort();
e1.add<Mass>();
});
test_assert(false);
}
void Table_iter_without_components(void) {
flecs::world ecs;
ecs.entity().add<Position>();
auto e2 = ecs.entity().add<Velocity>();
ecs.filter<Position>()
.iter([&](flecs::iter& it) {
e2.add<Mass>();
});
test_assert(e2.has<Mass>());
}
void Table_iter_without_components_locked(void) {
install_test_abort();
flecs::world ecs;
auto e1 = ecs.entity().add<Position>();
ecs.filter<Position>()
.iter([&](flecs::iter& it) {
test_expect_abort();
e1.add<Mass>();
});
test_assert(false);
}
void Table_multi_get(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>().add<Velocity>();
auto e2 = ecs.entity().add<Position>();
test_bool(true, e1.get([&](const Position& p, const Velocity& v) {
e2.add<Mass>();
}));
test_assert(e2.has<Mass>());
}
void Table_multi_get_locked(void) {
install_test_abort();
flecs::world ecs;
auto e1 = ecs.entity().add<Position>().add<Velocity>();
auto e2 = ecs.entity().add<Position>();
test_bool(true, e1.get([&](const Position& p, const Velocity& v) {
test_expect_abort();
e2.add<Velocity>();
}));
test_assert(false);
}
void Table_multi_set(void) {
flecs::world ecs;
auto e1 = ecs.entity().add<Position>().add<Velocity>();
auto e2 = ecs.entity().add<Position>();
e1.set([&](Position& p, Velocity& v) {
e2.add<Mass>();
});
test_assert(e2.has<Mass>());
}
void Table_multi_set_locked(void) {
install_test_abort();
flecs::world ecs;
auto e1 = ecs.entity().add<Position>().add<Velocity>();
auto e2 = ecs.entity().add<Position>();
e1.set([&](Position& p, Velocity& v) {
test_expect_abort();
e2.add<Velocity>();
});
test_assert(false);
}
void Table_count(void) {
flecs::world ecs;
flecs::entity e = ecs.entity().set<Position>({10, 20});
ecs.entity().set<Position>({20, 30});
ecs.entity().set<Position>({30, 40});
flecs::table table = e.table();
test_int(table.count(), 3);
}
void Table_has_id(void) {
flecs::world ecs;
flecs::entity t1 = ecs.entity();
flecs::entity t2 = ecs.entity();
flecs::entity t3 = ecs.entity();
flecs::entity e = ecs.entity()
.add(t1)
.add(t2);
ecs.entity()
.add(t1)
.add(t2);
ecs.entity()
.add(t1)
.add(t2);
flecs::table table = e.table();
test_assert(table.has(t1));
test_assert(table.has(t2));
test_assert(!table.has(t3));
}
void Table_has_T(void) {
flecs::world ecs;
flecs::entity e = ecs.entity()
.set<Position>({10, 20})
.set<Velocity>({1, 2});
ecs.entity()
.set<Position>({20, 30})
.set<Velocity>({2, 3});
ecs.entity()
.set<Position>({30, 40})
.set<Velocity>({3, 4});
flecs::table table = e.table();
test_assert(table.has<Position>());
test_assert(table.has<Velocity>());
test_assert(!table.has<Mass>());
}
void Table_has_pair_r_t(void) {
flecs::world ecs;
flecs::entity r = ecs.entity();
flecs::entity t1 = ecs.entity();
flecs::entity t2 = ecs.entity();
flecs::entity t3 = ecs.entity();
flecs::entity e = ecs.entity()
.add(r, t1)
.add(r, t2);
ecs.entity()
.add(r, t1)
.add(r, t2);
ecs.entity()
.add(r, t1)
.add(r, t2);
flecs::table table = e.table();
test_assert(table.has(r, t1));
test_assert(table.has(r, t2));
test_assert(!table.has(r, t3));
}
void Table_has_pair_R_t(void) {
flecs::world ecs;
struct R { };
flecs::entity t1 = ecs.entity();
flecs::entity t2 = ecs.entity();
flecs::entity t3 = ecs.entity();
flecs::entity e = ecs.entity()
.add<R>(t1)
.add<R>(t2);
ecs.entity()
.add<R>(t1)
.add<R>(t2);
ecs.entity()
.add<R>(t1)
.add<R>(t2);
flecs::table table = e.table();
test_assert(table.has<R>(t1));
test_assert(table.has<R>(t2));
test_assert(!table.has<R>(t3));
}
void Table_has_pair_R_T(void) {
flecs::world ecs;
struct R { };
struct T1 { };
struct T2 { };
struct T3 { };
flecs::entity e = ecs.entity()
.add<R,T1>()
.add<R,T2>();
ecs.entity()
.add<R,T1>()
.add<R,T2>();
ecs.entity()
.add<R,T1>()
.add<R,T2>();
flecs::table table = e.table();
test_assert((table.has<R, T1>()));
test_assert((table.has<R, T2>()));
test_assert((!table.has<R, T3>()));
}
void Table_get_id(void) {
flecs::world ecs;
flecs::entity e = ecs.entity()
.set<Position>({10, 20})
.set<Velocity>({1, 2});
ecs.entity()
.set<Position>({20, 30})
.set<Velocity>({2, 3});
ecs.entity()
.set<Position>({30, 40})
.set<Velocity>({3, 4});
flecs::table table = e.table();
void *ptr = table.get(ecs.id<Position>());
Position *p = static_cast<Position*>(ptr);
test_assert(p != NULL);
test_int(p[0].x, 10);
test_int(p[0].y, 20);
test_int(p[1].x, 20);
test_int(p[1].y, 30);
test_int(p[2].x, 30);
test_int(p[2].y, 40);
ptr = table.get(ecs.id<Velocity>());
Velocity *v = static_cast<Velocity*>(ptr);
test_assert(v != NULL);
test_int(v[0].x, 1);
test_int(v[0].y, 2);
test_int(v[1].x, 2);
test_int(v[1].y, 3);
test_int(v[2].x, 3);
test_int(v[2].y, 4);
}
void Table_get_T(void) {
flecs::world ecs;
flecs::entity e = ecs.entity()
.set<Position>({10, 20})
.set<Velocity>({1, 2});
ecs.entity()
.set<Position>({20, 30})
.set<Velocity>({2, 3});
ecs.entity()
.set<Position>({30, 40})
.set<Velocity>({3, 4});
flecs::table table = e.table();
Position *p = table.get<Position>();
test_assert(p != NULL);
test_int(p[0].x, 10);
test_int(p[0].y, 20);
test_int(p[1].x, 20);
test_int(p[1].y, 30);
test_int(p[2].x, 30);
test_int(p[2].y, 40);
Velocity *v = table.get<Velocity>();
test_assert(v != NULL);
test_int(v[0].x, 1);
test_int(v[0].y, 2);
test_int(v[1].x, 2);
test_int(v[1].y, 3);
test_int(v[2].x, 3);
test_int(v[2].y, 4);
}
void Table_get_pair_r_t(void) {
flecs::world ecs;
struct Tgt { };
flecs::entity e = ecs.entity()
.set<Position, Tgt>({10, 20})
.set<Velocity, Tgt>({1, 2});
ecs.entity()
.set<Position, Tgt>({20, 30})
.set<Velocity, Tgt>({2, 3});
ecs.entity()
.set<Position, Tgt>({30, 40})
.set<Velocity, Tgt>({3, 4});
flecs::table table = e.table();
void *ptr = table.get(ecs.id<Position>(), ecs.id<Tgt>());
Position *p = static_cast<Position*>(ptr);
test_assert(p != NULL);
test_int(p[0].x, 10);
test_int(p[0].y, 20);
test_int(p[1].x, 20);
test_int(p[1].y, 30);
test_int(p[2].x, 30);
test_int(p[2].y, 40);
ptr = table.get(ecs.id<Velocity>(), ecs.id<Tgt>());
Velocity *v = static_cast<Velocity*>(ptr);
test_assert(v != NULL);
test_int(v[0].x, 1);
test_int(v[0].y, 2);
test_int(v[1].x, 2);
test_int(v[1].y, 3);
test_int(v[2].x, 3);
test_int(v[2].y, 4);
}
void Table_get_pair_R_t(void) {
flecs::world ecs;
struct Tgt { };
flecs::entity e = ecs.entity()
.set<Position, Tgt>({10, 20})
.set<Velocity, Tgt>({1, 2});
ecs.entity()
.set<Position, Tgt>({20, 30})
.set<Velocity, Tgt>({2, 3});
ecs.entity()
.set<Position, Tgt>({30, 40})
.set<Velocity, Tgt>({3, 4});
flecs::table table = e.table();
void *ptr = table.get<Position>(ecs.id<Tgt>());
Position *p = static_cast<Position*>(ptr);
test_assert(p != NULL);
test_int(p[0].x, 10);
test_int(p[0].y, 20);
test_int(p[1].x, 20);
test_int(p[1].y, 30);
test_int(p[2].x, 30);
test_int(p[2].y, 40);
ptr = table.get<Velocity>(ecs.id<Tgt>());
Velocity *v = static_cast<Velocity*>(ptr);
test_assert(v != NULL);
test_int(v[0].x, 1);
test_int(v[0].y, 2);
test_int(v[1].x, 2);
test_int(v[1].y, 3);
test_int(v[2].x, 3);
test_int(v[2].y, 4);
}
void Table_get_pair_R_T(void) {
flecs::world ecs;
struct Tgt { };
flecs::entity e = ecs.entity()
.set<Position, Tgt>({10, 20})
.set<Velocity, Tgt>({1, 2});
ecs.entity()
.set<Position, Tgt>({20, 30})
.set<Velocity, Tgt>({2, 3});
ecs.entity()
.set<Position, Tgt>({30, 40})
.set<Velocity, Tgt>({3, 4});
flecs::table table = e.table();
void *ptr = table.get<Position, Tgt>();
Position *p = static_cast<Position*>(ptr);
test_assert(p != NULL);
test_int(p[0].x, 10);
test_int(p[0].y, 20);
test_int(p[1].x, 20);
test_int(p[1].y, 30);
test_int(p[2].x, 30);
test_int(p[2].y, 40);
ptr = table.get<Velocity, Tgt>();
Velocity *v = static_cast<Velocity*>(ptr);
test_assert(v != NULL);
test_int(v[0].x, 1);
test_int(v[0].y, 2);
test_int(v[1].x, 2);
test_int(v[1].y, 3);
test_int(v[2].x, 3);
test_int(v[2].y, 4);
}
void Table_range_get_id(void) {
flecs::world ecs;
ecs.entity()
.set<Position>({10, 20})
.set<Velocity>({1, 2});
flecs::entity e = ecs.entity()
.set<Position>({20, 30})
.set<Velocity>({2, 3});
ecs.entity()
.set<Position>({30, 40})
.set<Velocity>({3, 4});
flecs::table_range table = e.range();
void *ptr = table.get(ecs.id<Position>());
Position *p = static_cast<Position*>(ptr);
test_assert(p != NULL);
test_int(p[0].x, 20);
test_int(p[0].y, 30);
ptr = table.get(ecs.id<Velocity>());
Velocity *v = static_cast<Velocity*>(ptr);
test_assert(v != NULL);
test_int(v[0].x, 2);
test_int(v[0].y, 3);
}
void Table_range_get_T(void) {
flecs::world ecs;
ecs.entity()
.set<Position>({10, 20})
.set<Velocity>({1, 2});
flecs::entity e = ecs.entity()
.set<Position>({20, 30})
.set<Velocity>({2, 3});
ecs.entity()
.set<Position>({30, 40})
.set<Velocity>({3, 4});
flecs::table_range table = e.range();
Position *p = table.get<Position>();
test_assert(p != NULL);
test_int(p[0].x, 20);
test_int(p[0].y, 30);
Velocity *v = table.get<Velocity>();
test_assert(v != NULL);
test_int(v[0].x, 2);
test_int(v[0].y, 3);
}
void Table_range_get_pair_r_t(void) {
flecs::world ecs;
struct Tgt { };
ecs.entity()
.set<Position, Tgt>({10, 20})
.set<Velocity, Tgt>({1, 2});
flecs::entity e = ecs.entity()
.set<Position, Tgt>({20, 30})
.set<Velocity, Tgt>({2, 3});
ecs.entity()
.set<Position, Tgt>({30, 40})
.set<Velocity, Tgt>({3, 4});
flecs::table_range table = e.range();
void *ptr = table.get(ecs.id<Position>(), ecs.id<Tgt>());
Position *p = static_cast<Position*>(ptr);
test_assert(p != NULL);
test_int(p[0].x, 20);
test_int(p[0].y, 30);
ptr = table.get(ecs.id<Velocity>(), ecs.id<Tgt>());
Velocity *v = static_cast<Velocity*>(ptr);
test_assert(v != NULL);
test_int(v[0].x, 2);
test_int(v[0].y, 3);
}
void Table_range_get_pair_R_t(void) {
flecs::world ecs;
struct Tgt { };
ecs.entity()
.set<Position, Tgt>({10, 20})
.set<Velocity, Tgt>({1, 2});
flecs::entity e = ecs.entity()
.set<Position, Tgt>({20, 30})
.set<Velocity, Tgt>({2, 3});
ecs.entity()
.set<Position, Tgt>({30, 40})
.set<Velocity, Tgt>({3, 4});
flecs::table_range table = e.range();
Position *p = table.get<Position>(ecs.id<Tgt>());
test_assert(p != NULL);
test_int(p[0].x, 20);
test_int(p[0].y, 30);
Velocity *v = table.get<Velocity>(ecs.id<Tgt>());
test_assert(v != NULL);
test_int(v[0].x, 2);
test_int(v[0].y, 3);
}
void Table_range_get_pair_R_T(void) {
flecs::world ecs;
struct Tgt { };
ecs.entity()
.set<Position, Tgt>({10, 20})
.set<Velocity, Tgt>({1, 2});
flecs::entity e = ecs.entity()
.set<Position, Tgt>({20, 30})
.set<Velocity, Tgt>({2, 3});
ecs.entity()
.set<Position, Tgt>({30, 40})
.set<Velocity, Tgt>({3, 4});
flecs::table_range table = e.range();
Position *p = table.get<Position, Tgt>();
test_assert(p != NULL);
test_int(p[0].x, 20);
test_int(p[0].y, 30);
Velocity *v = table.get<Velocity, Tgt>();
test_assert(v != NULL);
test_int(v[0].x, 2);
test_int(v[0].y, 3);
}
void Table_get_depth(void) {
flecs::world world;
flecs::entity e1 = world.entity();
flecs::entity e2 = world.entity().child_of(e1);
flecs::entity e3 = world.entity().child_of(e2);
flecs::entity e4 = world.entity().child_of(e3);
test_int(1, e2.table().depth(flecs::ChildOf));
test_int(2, e3.table().depth(flecs::ChildOf));
test_int(3, e4.table().depth(flecs::ChildOf));
}
void Table_get_depth_w_type(void) {
flecs::world world;
struct Rel { };
world.component<Rel>().add(flecs::Traversable);
flecs::entity e1 = world.entity();
flecs::entity e2 = world.entity().add<Rel>(e1);
flecs::entity e3 = world.entity().add<Rel>(e2);
flecs::entity e4 = world.entity().add<Rel>(e3);
test_int(1, e2.table().depth<Rel>());
test_int(2, e3.table().depth<Rel>());
test_int(3, e4.table().depth<Rel>());
}
void Table_iter_type(void) {
flecs::world ecs;
auto e = ecs.entity()
.add<Position>()
.add<Velocity>();
auto table = e.table();
int32_t count = 0;
for (const auto id : table.type()) {
count ++;
test_assert(id == ecs.id<Position>() || id == ecs.id<Velocity>());
}
test_int(count, 2);
}
void Table_get_T_enum(void) {
flecs::world ecs;
flecs::entity e = ecs.entity()
.set<Number>(Number::One);
ecs.entity()
.set<Number>(Number::Two);
ecs.entity()
.set<Number>(Number::Three);
flecs::table table = e.table();
Number *n = table.get<Number>();
test_assert(n != NULL);
test_int(n[0], Number::One);
test_int(n[1], Number::Two);
test_int(n[2], Number::Three);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,201 @@
#include <cpp_api.h>
void WorldFactory_entity(void) {
flecs::world ecs;
auto e = ecs.entity();
test_assert(e.id() != 0);
}
void WorldFactory_entity_w_name(void) {
flecs::world ecs;
auto e = ecs.entity("MyName");
test_assert(e.id() != 0);
test_str(e.name().c_str(), "MyName");
}
void WorldFactory_entity_w_id(void) {
flecs::world ecs;
auto e = ecs.entity(100);
test_assert(e.id() == 100);
}
void WorldFactory_prefab(void) {
flecs::world ecs;
auto e = ecs.prefab();
test_assert(e.id() != 0);
test_assert(e.has(flecs::Prefab));
}
void WorldFactory_prefab_w_name(void) {
flecs::world ecs;
auto e = ecs.prefab("MyName");
test_assert(e.id() != 0);
test_assert(e.has(flecs::Prefab));
test_str(e.name().c_str(), "MyName");
}
void WorldFactory_system(void) {
flecs::world ecs;
auto s = ecs.system<Position, const Velocity>()
.each([](flecs::entity e, Position& p, const Velocity& v) {
p.x += v.x;
p.y += v.y;
});
test_assert(s.id() != 0);
auto e = ecs.entity()
.set<Position>({10, 20})
.set<Velocity>({1, 2});
ecs.progress();
const Position *p = e.get<Position>();
test_int(p->x, 11);
test_int(p->y, 22);
}
void WorldFactory_system_w_name(void) {
flecs::world ecs;
auto s = ecs.system<Position, const Velocity>("MySystem")
.each([](flecs::entity e, Position& p, const Velocity& v) {
p.x += v.x;
p.y += v.y;
});
test_assert(s.id() != 0);
test_str(s.name().c_str(), "MySystem");
auto e = ecs.entity()
.set<Position>({10, 20})
.set<Velocity>({1, 2});
ecs.progress();
const Position *p = e.get<Position>();
test_int(p->x, 11);
test_int(p->y, 22);
}
void WorldFactory_system_w_expr(void) {
flecs::world ecs;
ecs.component<Position>();
ecs.component<Velocity>();
auto s = ecs.system<>("MySystem")
.expr("Position, [in] Velocity")
.iter([](flecs::iter it) {
flecs::column<Position> p(it, 1);
flecs::column<const Velocity> v(it, 2);
for (auto i : it) {
p[i].x += v[i].x;
p[i].y += v[i].y;
}
});
test_assert(s.id() != 0);
test_str(s.name().c_str(), "MySystem");
auto e = ecs.entity()
.set<Position>({10, 20})
.set<Velocity>({1, 2});
ecs.progress();
const Position *p = e.get<Position>();
test_int(p->x, 11);
test_int(p->y, 22);
}
void WorldFactory_query(void) {
flecs::world ecs;
auto q = ecs.query<Position, const Velocity>();
auto e = ecs.entity()
.set<Position>({10, 20})
.set<Velocity>({1, 2});
q.each([](flecs::entity e, Position& p, const Velocity& v) {
p.x += v.x;
p.y += v.y;
});
const Position *p = e.get<Position>();
test_int(p->x, 11);
test_int(p->y, 22);
}
void WorldFactory_query_w_expr(void) {
flecs::world ecs;
ecs.component<Position>();
ecs.component<Velocity>();
auto q = ecs.query_builder<>().expr("Position, [in] Velocity").build();
auto e = ecs.entity()
.set<Position>({10, 20})
.set<Velocity>({1, 2});
q.iter([](flecs::iter it) {
flecs::column<Position> p(it, 1);
flecs::column<const Velocity> v(it, 2);
for (auto i : it) {
p[i].x += v[i].x;
p[i].y += v[i].y;
}
});
const Position *p = e.get<Position>();
test_int(p->x, 11);
test_int(p->y, 22);
}
void WorldFactory_snapshot(void) {
flecs::world ecs;
ecs.component<Position>();
ecs.component<Velocity>();
auto e = ecs.entity()
.set<Position>({10, 20})
.set<Velocity>({1, 2});
auto s = ecs.snapshot();
e.set<Position>({11, 22});
s.restore();
const Position *p = e.get<Position>();
test_int(p->x, 11);
test_int(p->y, 22);
}
class MyModule {
public:
MyModule(flecs::world& ecs) {
ecs.module<MyModule>();
ecs.component<Position>();
}
};
void WorldFactory_module(void) {
flecs::world ecs;
ecs.import<MyModule>();
auto p = ecs.lookup("MyModule::Position");
test_assert(p.id() != 0);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
#include <cpp_api.h>
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);
}