1372 lines
34 KiB
C++
1372 lines
34 KiB
C++
#include <cpp_api.h>
|
|
|
|
flecs::opaque<std::string> std_string_support(flecs::world&) {
|
|
flecs::opaque<std::string> ts;
|
|
|
|
// Let reflection framework know what kind of type this is
|
|
ts.as_type(flecs::String);
|
|
|
|
// Forward std::string value to (JSON/...) serializer
|
|
ts.serialize([](const flecs::serializer *s, const std::string *data) {
|
|
const char *value = data->c_str();
|
|
return s->value(flecs::String, &value);
|
|
});
|
|
|
|
// Serialize string into std::string
|
|
ts.assign_string([](std::string *data, const char *value) {
|
|
*data = value;
|
|
});
|
|
|
|
return ts;
|
|
}
|
|
|
|
template <typename T>
|
|
flecs::opaque<std::vector<T>, T> std_vector_support(flecs::world& world) {
|
|
flecs::opaque<std::vector<T>, T> ts;
|
|
|
|
// Let reflection framework know what kind of type this is
|
|
ts.as_type(world.vector<T>());
|
|
|
|
// Forward elements of std::vector value to (JSON/...) serializer
|
|
ts.serialize([](const flecs::serializer *s, const std::vector<T> *data) {
|
|
for (const auto& el : *data) {
|
|
s->value(el);
|
|
}
|
|
return 0;
|
|
});
|
|
|
|
// Return vector count
|
|
ts.count([](const std::vector<T> *data) {
|
|
return data->size();
|
|
});
|
|
|
|
// Ensure element exists, return
|
|
ts.ensure_element([](std::vector<T> *data, size_t elem) {
|
|
if (data->size() <= elem) {
|
|
data->resize(elem + 1);
|
|
}
|
|
|
|
return &data->data()[elem];
|
|
});
|
|
|
|
// Resize contents of vector
|
|
ts.resize([](std::vector<T> *data, size_t size) {
|
|
data->resize(size);
|
|
});
|
|
|
|
return ts;
|
|
}
|
|
|
|
|
|
void Meta_struct(void) {
|
|
flecs::world ecs;
|
|
|
|
struct Test {
|
|
int32_t a;
|
|
float b;
|
|
};
|
|
|
|
auto c = ecs.component<Test>()
|
|
.member<int32_t>("a")
|
|
.member<float>("b");
|
|
test_assert(c != 0);
|
|
|
|
auto a = c.lookup("a");
|
|
test_assert(a != 0);
|
|
test_assert( a.has<flecs::Member>() );
|
|
const flecs::Member *m = a.get<flecs::Member>();
|
|
test_uint(m->type, flecs::I32);
|
|
|
|
auto b = c.lookup("b");
|
|
test_assert(b != 0);
|
|
test_assert( b.has<flecs::Member>() );
|
|
m = b.get<flecs::Member>();
|
|
test_uint(m->type, flecs::F32);
|
|
}
|
|
|
|
void Meta_nested_struct(void) {
|
|
flecs::world ecs;
|
|
|
|
struct Test {
|
|
int32_t x;
|
|
};
|
|
|
|
struct Nested {
|
|
Test a;
|
|
};
|
|
|
|
auto t = ecs.component<Test>()
|
|
.member<int32_t>("x");
|
|
|
|
auto n = ecs.component<Nested>()
|
|
.member(t, "a");
|
|
test_assert(n != 0);
|
|
|
|
auto a = n.lookup("a");
|
|
test_assert(a != 0);
|
|
test_assert( a.has<flecs::Member>() );
|
|
const flecs::Member *m = a.get<flecs::Member>();
|
|
test_uint(m->type, t);
|
|
}
|
|
|
|
void Meta_struct_w_portable_type(void) {
|
|
flecs::world ecs;
|
|
|
|
struct Test {
|
|
uintptr_t a;
|
|
uintptr_t b;
|
|
flecs::entity_t c;
|
|
flecs::entity_t d;
|
|
};
|
|
|
|
auto t = ecs.component<Test>()
|
|
.member<uintptr_t>("a")
|
|
.member(flecs::Uptr, "b")
|
|
.member<flecs::entity_t>("c")
|
|
.member(flecs::Entity, "d");
|
|
test_assert(t != 0);
|
|
|
|
auto a = t.lookup("a");
|
|
test_assert(a != 0);
|
|
test_assert( a.has<flecs::Member>() );
|
|
const flecs::Member *m = a.get<flecs::Member>();
|
|
test_uint(m->type, ecs.component<uintptr_t>());
|
|
|
|
auto b = t.lookup("b");
|
|
test_assert(b != 0);
|
|
test_assert( b.has<flecs::Member>() );
|
|
m = b.get<flecs::Member>();
|
|
test_uint(m->type, flecs::Uptr);
|
|
|
|
auto c = t.lookup("c");
|
|
test_assert(c != 0);
|
|
test_assert( c.has<flecs::Member>() );
|
|
m = c.get<flecs::Member>();
|
|
test_uint(m->type, flecs::U64);
|
|
|
|
auto d = t.lookup("d");
|
|
test_assert(d != 0);
|
|
test_assert( d.has<flecs::Member>() );
|
|
m = d.get<flecs::Member>();
|
|
test_uint(m->type, flecs::Entity);
|
|
}
|
|
|
|
void Meta_units(void) {
|
|
struct Test {
|
|
int32_t meters;
|
|
int32_t custom_unit;
|
|
};
|
|
|
|
flecs::world ecs;
|
|
|
|
ecs.import<flecs::units>();
|
|
|
|
auto custom_unit = ecs.entity("some_unit").unit("u");
|
|
test_assert(custom_unit != 0);
|
|
test_str(custom_unit.name(), "some_unit");
|
|
|
|
const flecs::Unit *unit = custom_unit.get<flecs::Unit>();
|
|
test_assert(unit != nullptr);
|
|
test_str(unit->symbol, "u");
|
|
|
|
auto t = ecs.component<Test>()
|
|
.member<int32_t, flecs::units::length::Meters>("meters")
|
|
.member<int32_t>(custom_unit, "custom_unit");
|
|
test_assert(t != 0);
|
|
|
|
flecs::entity m_meters = t.lookup("meters");
|
|
test_assert(m_meters != 0);
|
|
const flecs::Member *m = m_meters.get<flecs::Member>();
|
|
test_assert(m != nullptr);
|
|
test_uint(m->type, flecs::I32);
|
|
test_uint(m->unit, ecs.id<flecs::units::length::Meters>());
|
|
|
|
flecs::entity m_custom_unit = t.lookup("custom_unit");
|
|
test_assert(m_custom_unit != 0);
|
|
m = m_custom_unit.get<flecs::Member>();
|
|
test_assert(m != nullptr);
|
|
test_uint(m->type, flecs::I32);
|
|
test_uint(m->unit, custom_unit);
|
|
}
|
|
|
|
void Meta_unit_w_quantity(void) {
|
|
struct Test {
|
|
int32_t m_1;
|
|
int32_t m_2;
|
|
};
|
|
|
|
flecs::world ecs;
|
|
|
|
ecs.import<flecs::units>();
|
|
|
|
auto custom_quantity = ecs.entity().quantity();
|
|
auto unit_1 = ecs.entity().unit("u1").quantity(custom_quantity);
|
|
auto unit_2 = ecs.entity().unit("u2").quantity<flecs::units::Length>();
|
|
|
|
test_assert(unit_1.has(flecs::Quantity, custom_quantity));
|
|
test_assert(unit_2.has(flecs::Quantity, ecs.id<flecs::units::Length>()));
|
|
|
|
auto t = ecs.component<Test>()
|
|
.member<int32_t>(unit_1, "m_1")
|
|
.member<int32_t>(unit_2, "m_2");
|
|
test_assert(t != 0);
|
|
|
|
flecs::entity m_1 = t.lookup("m_1");
|
|
test_assert(m_1 != 0);
|
|
const flecs::Member *m = m_1.get<flecs::Member>();
|
|
test_assert(m != nullptr);
|
|
test_uint(m->type, flecs::I32);
|
|
test_uint(m->unit, unit_1);
|
|
|
|
flecs::entity m_2 = t.lookup("m_2");
|
|
test_assert(m_2 != 0);
|
|
m = m_2.get<flecs::Member>();
|
|
test_assert(m != nullptr);
|
|
test_uint(m->type, flecs::I32);
|
|
test_uint(m->unit, unit_2);
|
|
}
|
|
|
|
void Meta_unit_w_prefix(void) {
|
|
struct Test {
|
|
int32_t m_1;
|
|
int32_t m_2;
|
|
};
|
|
|
|
flecs::world ecs;
|
|
|
|
ecs.import<flecs::units>();
|
|
|
|
auto prefix = ecs.entity().unit_prefix("p", 100, 1);
|
|
|
|
auto unit_1 = ecs.entity().unit("U1");
|
|
const flecs::Unit *unit = unit_1.get<flecs::Unit>();
|
|
test_assert(unit != nullptr);
|
|
test_str(unit->symbol, "U1");
|
|
|
|
auto unit_2 = ecs.entity().unit(prefix, unit_1);
|
|
unit = unit_2.get<flecs::Unit>();
|
|
test_assert(unit != nullptr);
|
|
test_str(unit->symbol, "pU1");
|
|
}
|
|
|
|
void Meta_unit_w_over(void) {
|
|
struct Test {
|
|
int32_t m_1;
|
|
int32_t m_2;
|
|
};
|
|
|
|
flecs::world ecs;
|
|
|
|
ecs.import<flecs::units>();
|
|
|
|
auto prefix = ecs.entity().unit_prefix("p", 100, 1);
|
|
|
|
auto unit_0 = ecs.entity().unit("U0");
|
|
const flecs::Unit *unit = unit_0.get<flecs::Unit>();
|
|
test_assert(unit != nullptr);
|
|
test_str(unit->symbol, "U0");
|
|
|
|
auto unit_1 = ecs.entity().unit("U1");
|
|
unit = unit_1.get<flecs::Unit>();
|
|
test_assert(unit != nullptr);
|
|
test_str(unit->symbol, "U1");
|
|
|
|
auto unit_2 = ecs.entity().unit(prefix, unit_1, unit_0);
|
|
unit = unit_2.get<flecs::Unit>();
|
|
test_assert(unit != nullptr);
|
|
test_str(unit->symbol, "pU1/U0");
|
|
}
|
|
|
|
void Meta_partial_struct(void) {
|
|
flecs::world ecs;
|
|
|
|
auto c = ecs.component<Position>()
|
|
.member<float>("x");
|
|
test_assert(c != 0);
|
|
|
|
const flecs::Component *ptr = c.get<flecs::Component>();
|
|
test_int(ptr->size, 8);
|
|
test_int(ptr->alignment, 4);
|
|
|
|
auto xe = c.lookup("x");
|
|
test_assert(xe != 0);
|
|
test_assert( xe.has<flecs::Member>() );
|
|
const flecs::Member *x = xe.get<flecs::Member>();
|
|
test_uint(x->type, flecs::F32);
|
|
test_uint(x->offset, 0);
|
|
}
|
|
|
|
void Meta_partial_struct_custom_offset(void) {
|
|
flecs::world ecs;
|
|
|
|
auto c = ecs.component<Position>()
|
|
.member<float>("y", 1, offsetof(Position, y));
|
|
test_assert(c != 0);
|
|
|
|
const flecs::Component *ptr = c.get<flecs::Component>();
|
|
test_int(ptr->size, 8);
|
|
test_int(ptr->alignment, 4);
|
|
|
|
auto xe = c.lookup("y");
|
|
test_assert(xe != 0);
|
|
test_assert( xe.has<flecs::Member>() );
|
|
const flecs::Member *x = xe.get<flecs::Member>();
|
|
test_uint(x->type, flecs::F32);
|
|
test_uint(x->offset, 4);
|
|
}
|
|
|
|
struct Toppings : flecs::bitmask {
|
|
static constexpr uint32_t Bacon = 0x1;
|
|
static constexpr uint32_t Lettuce = 0x2;
|
|
static constexpr uint32_t Tomato = 0x4;
|
|
};
|
|
|
|
struct Sandwich {
|
|
uint32_t toppings;
|
|
};
|
|
|
|
void Meta_bitmask(void) {
|
|
flecs::world ecs;
|
|
|
|
// Register components with reflection data
|
|
ecs.component<Toppings>()
|
|
.bit("Bacon", Toppings::Bacon)
|
|
.bit("Lettuce", Toppings::Lettuce)
|
|
.bit("Tomato", Toppings::Tomato);
|
|
|
|
ecs.component<Sandwich>()
|
|
.member<Toppings>("toppings");
|
|
|
|
// Create entity with Position as usual
|
|
auto e = ecs.entity()
|
|
.set<Sandwich>({Toppings::Bacon | Toppings::Lettuce});
|
|
|
|
// Convert position component to flecs expression string
|
|
const Sandwich *ptr = e.get<Sandwich>();
|
|
test_str(ecs.to_expr(ptr).c_str(), "{toppings: Lettuce|Bacon}");
|
|
}
|
|
|
|
struct Int {
|
|
int32_t v;
|
|
};
|
|
|
|
struct TVector {
|
|
std::vector<int> v;
|
|
};
|
|
|
|
struct TString {
|
|
std::string v;
|
|
};
|
|
|
|
struct TVectorString {
|
|
std::vector<int> v;
|
|
std::string s;
|
|
};
|
|
|
|
struct TStringVector {
|
|
std::string s;
|
|
std::vector<int> v;
|
|
};
|
|
|
|
struct TStringString {
|
|
std::string s1;
|
|
std::string s2;
|
|
};
|
|
|
|
struct TVectorVector {
|
|
std::vector<int> v1;
|
|
std::vector<int> v2;
|
|
};
|
|
|
|
struct TVectorVectorString {
|
|
std::vector<int> v1;
|
|
std::vector<int> v2;
|
|
std::string s;
|
|
};
|
|
|
|
struct TVectorStringVector {
|
|
std::vector<int> v1;
|
|
std::string s;
|
|
std::vector<int> v2;
|
|
};
|
|
|
|
static
|
|
int Int_serialize(const flecs::serializer *s, const Int *data) {
|
|
return s->value(data->v);
|
|
}
|
|
|
|
static
|
|
int String_serialize(const flecs::serializer *s, const std::string *data) {
|
|
const char *str = data->c_str();
|
|
return s->value(flecs::String, &str);
|
|
}
|
|
|
|
template <typename Elem>
|
|
int Vector_serialize(const flecs::serializer *ser, const std::vector<Elem> *data) {
|
|
for (const auto& el : *data) {
|
|
if (ser->value(el)) {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void Meta_custom_i32_to_json(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<Int>().opaque(flecs::I32)
|
|
.serialize(Int_serialize);
|
|
|
|
Int v = {10};
|
|
flecs::string json = ecs.to_json(&v);
|
|
test_str(json, "10");
|
|
}
|
|
|
|
void Meta_custom_std_string_to_json(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<std::string>().opaque(flecs::String)
|
|
.serialize(String_serialize);
|
|
|
|
std::string v = {"Hello World"};
|
|
flecs::string json = ecs.to_json(&v);
|
|
test_str(json, "\"Hello World\"");
|
|
}
|
|
|
|
void Meta_custom_std_vector_i32_to_json(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<std::vector<int>>().opaque(ecs.vector<int>())
|
|
.serialize(Vector_serialize<int>);
|
|
|
|
std::vector<int> v = {1, 2, 3};
|
|
flecs::string json = ecs.to_json(&v);
|
|
test_str(json, "[1, 2, 3]");
|
|
}
|
|
|
|
void Meta_custom_std_vector_std_string_to_json(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<std::string>().opaque(flecs::String)
|
|
.serialize(String_serialize);
|
|
|
|
ecs.component<std::vector<std::string>>().opaque(ecs.vector(flecs::String))
|
|
.serialize(Vector_serialize<std::string>);
|
|
|
|
std::vector<std::string> v = {"hello", "world", "foo"};
|
|
flecs::string json = ecs.to_json(&v);
|
|
test_str(json, "[\"hello\", \"world\", \"foo\"]");
|
|
}
|
|
|
|
void Meta_type_w_std_vector(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<std::vector<int>>().opaque(ecs.vector<int>())
|
|
.serialize(Vector_serialize<int>);
|
|
|
|
ecs.component<TVector>()
|
|
.member<std::vector<int>>("v");
|
|
|
|
TVector v = {{1, 2, 3}};
|
|
flecs::string json = ecs.to_json(&v);
|
|
test_str(json, "{\"v\":[1, 2, 3]}");
|
|
}
|
|
|
|
void Meta_type_w_std_string(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<std::string>().opaque(flecs::String)
|
|
.serialize(String_serialize);
|
|
|
|
ecs.component<TString>()
|
|
.member<std::string>("v");
|
|
|
|
TString v = {"hello world"};
|
|
flecs::string json = ecs.to_json(&v);
|
|
test_str(json, "{\"v\":\"hello world\"}");
|
|
}
|
|
|
|
void Meta_type_w_std_vector_std_string(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<std::vector<int>>().opaque(ecs.vector<int>())
|
|
.serialize(Vector_serialize<int>);
|
|
|
|
ecs.component<std::string>().opaque(flecs::String)
|
|
.serialize(String_serialize);
|
|
|
|
ecs.component<TVectorString>()
|
|
.member<std::vector<int>>("v")
|
|
.member<std::string>("s");
|
|
|
|
TVectorString v = {{1, 2, 3}, "hello world"};
|
|
flecs::string json = ecs.to_json(&v);
|
|
test_str(json, "{\"v\":[1, 2, 3], \"s\":\"hello world\"}");
|
|
}
|
|
|
|
void Meta_type_w_std_string_std_vector(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<std::vector<int>>().opaque(ecs.vector<int>())
|
|
.serialize(Vector_serialize<int>);
|
|
|
|
ecs.component<std::string>().opaque(flecs::String)
|
|
.serialize(String_serialize);
|
|
|
|
ecs.component<TStringVector>()
|
|
.member<std::string>("s")
|
|
.member<std::vector<int>>("v");
|
|
|
|
TStringVector v = {"hello world", {1, 2, 3}};
|
|
flecs::string json = ecs.to_json(&v);
|
|
test_str(json, "{\"s\":\"hello world\", \"v\":[1, 2, 3]}");
|
|
}
|
|
|
|
void Meta_type_w_std_string_std_string(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<std::vector<int>>().opaque(ecs.vector<int>())
|
|
.serialize(Vector_serialize<int>);
|
|
|
|
ecs.component<std::string>().opaque(flecs::String)
|
|
.serialize(String_serialize);
|
|
|
|
ecs.component<TStringString>()
|
|
.member<std::string>("s1")
|
|
.member<std::string>("s2");
|
|
|
|
TStringString v = {"hello world", "foo bar"};
|
|
flecs::string json = ecs.to_json(&v);
|
|
test_str(json, "{\"s1\":\"hello world\", \"s2\":\"foo bar\"}");
|
|
}
|
|
|
|
void Meta_type_w_std_vector_std_vector(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<std::vector<int>>().opaque(ecs.vector<int>())
|
|
.serialize(Vector_serialize<int>);
|
|
|
|
ecs.component<std::string>().opaque(flecs::String)
|
|
.serialize(String_serialize);
|
|
|
|
ecs.component<TVectorVector>()
|
|
.member<std::vector<int>>("v1")
|
|
.member<std::vector<int>>("v2");
|
|
|
|
TVectorVector v = {{1, 2, 3}, {4, 5, 6}};
|
|
flecs::string json = ecs.to_json(&v);
|
|
test_str(json, "{\"v1\":[1, 2, 3], \"v2\":[4, 5, 6]}");
|
|
}
|
|
|
|
void Meta_type_w_std_vector_std_string_std_vector(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<std::vector<int>>().opaque(ecs.vector<int>())
|
|
.serialize(Vector_serialize<int>);
|
|
|
|
ecs.component<std::string>().opaque(flecs::String)
|
|
.serialize(String_serialize);
|
|
|
|
ecs.component<TVectorStringVector>()
|
|
.member<std::vector<int>>("v1")
|
|
.member<std::string>("s")
|
|
.member<std::vector<int>>("v2");
|
|
|
|
TVectorStringVector v = {{1, 2, 3}, "hello world", {4, 5, 6}};
|
|
flecs::string json = ecs.to_json(&v);
|
|
test_str(json, "{\"v1\":[1, 2, 3], \"s\":\"hello world\", \"v2\":[4, 5, 6]}");
|
|
}
|
|
|
|
void Meta_type_w_std_vector_std_vector_std_string(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<std::vector<int>>().opaque(ecs.vector<int>())
|
|
.serialize(Vector_serialize<int>);
|
|
|
|
ecs.component<std::string>().opaque(flecs::String)
|
|
.serialize(String_serialize);
|
|
|
|
ecs.component<TVectorVectorString>()
|
|
.member<std::vector<int>>("v1")
|
|
.member<std::vector<int>>("v2")
|
|
.member<std::string>("s");
|
|
|
|
TVectorVectorString v = {{1, 2, 3}, {4, 5, 6}, "hello world"};
|
|
flecs::string json = ecs.to_json(&v);
|
|
test_str(json, "{\"v1\":[1, 2, 3], \"v2\":[4, 5, 6], \"s\":\"hello world\"}");
|
|
}
|
|
|
|
void Meta_primitive_type(void) {
|
|
flecs::world ecs;
|
|
|
|
flecs::entity t = ecs.primitive(flecs::meta::I32);
|
|
test_assert(t != 0);
|
|
|
|
test_assert(t.has<flecs::Component>());
|
|
test_assert(t.has<flecs::MetaType>());
|
|
test_assert(t.has<flecs::Primitive>());
|
|
|
|
const flecs::Component *c = t.get<flecs::Component>();
|
|
test_assert(c != nullptr);
|
|
test_int(c->size, 4);
|
|
test_int(c->alignment, 4);
|
|
|
|
const flecs::MetaType *mt = t.get<flecs::MetaType>();
|
|
test_assert(mt != nullptr);
|
|
test_assert(mt->kind == flecs::meta::PrimitiveType);
|
|
|
|
const flecs::Primitive *pt = t.get<flecs::Primitive>();
|
|
test_assert(pt != nullptr);
|
|
test_assert(pt->kind == flecs::meta::I32);
|
|
}
|
|
|
|
void Meta_array_type(void) {
|
|
flecs::world ecs;
|
|
|
|
flecs::entity t = ecs.array(flecs::I32, 3);
|
|
test_assert(t != 0);
|
|
|
|
test_assert(t.has<flecs::Component>());
|
|
test_assert(t.has<flecs::MetaType>());
|
|
test_assert(t.has<flecs::Array>());
|
|
|
|
const flecs::Component *c = t.get<flecs::Component>();
|
|
test_assert(c != nullptr);
|
|
test_int(c->size, 3 * 4);
|
|
test_int(c->alignment, 4);
|
|
|
|
const flecs::MetaType *mt = t.get<flecs::MetaType>();
|
|
test_assert(mt != nullptr);
|
|
test_assert(mt->kind == flecs::meta::ArrayType);
|
|
|
|
const flecs::Array *at = t.get<flecs::Array>();
|
|
test_assert(at != nullptr);
|
|
test_assert(at->type == ecs.id<int32_t>());
|
|
test_int(at->count, 3);
|
|
}
|
|
|
|
void Meta_vector_type(void) {
|
|
flecs::world ecs;
|
|
|
|
flecs::entity t = ecs.vector(flecs::I32);
|
|
test_assert(t != 0);
|
|
|
|
test_assert(t.has<flecs::Component>());
|
|
test_assert(t.has<flecs::MetaType>());
|
|
test_assert(t.has<flecs::Vector>());
|
|
|
|
const flecs::Component *c = t.get<flecs::Component>();
|
|
test_assert(c != nullptr);
|
|
test_int(c->size, ECS_SIZEOF(ecs_vec_t));
|
|
test_int(c->alignment, ECS_SIZEOF(void*));
|
|
|
|
const flecs::MetaType *mt = t.get<flecs::MetaType>();
|
|
test_assert(mt != nullptr);
|
|
test_assert(mt->kind == flecs::meta::VectorType);
|
|
|
|
const flecs::Vector *vt = t.get<flecs::Vector>();
|
|
test_assert(vt != nullptr);
|
|
test_assert(vt->type == ecs.id<int32_t>());
|
|
}
|
|
|
|
void Meta_i32_from_json(void) {
|
|
flecs::world ecs;
|
|
|
|
int32_t v = 0;
|
|
const char *r = ecs.from_json(&v, "10");
|
|
test_str(r, "");
|
|
test_int(v, 10);
|
|
}
|
|
|
|
void Meta_struct_from_json(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<Position>()
|
|
.member<float>("x")
|
|
.member<float>("y");
|
|
|
|
Position v = {};
|
|
const char *r = ecs.from_json(&v, "{\"x\":10, \"y\":20}");
|
|
test_str(r, "");
|
|
test_int(v.x, 10);
|
|
test_int(v.y, 20);
|
|
}
|
|
|
|
void Meta_void_from_json(void) {
|
|
flecs::world ecs;
|
|
|
|
flecs::entity pos = ecs.component<Position>()
|
|
.member<float>("x")
|
|
.member<float>("y");
|
|
|
|
Position v = {};
|
|
void *ptr = &v;
|
|
const char *r = ecs.from_json(pos, ptr, "{\"x\":10, \"y\":20}");
|
|
test_str(r, "");
|
|
test_int(v.x, 10);
|
|
test_int(v.y, 20);
|
|
}
|
|
|
|
void Meta_entity_from_json_empty(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<Position>()
|
|
.member<float>("x")
|
|
.member<float>("y");
|
|
|
|
flecs::entity e = ecs.entity();
|
|
|
|
const char *r = e.from_json("{}");
|
|
test_str(r, "");
|
|
}
|
|
|
|
void Meta_entity_from_json_w_path(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<Position>()
|
|
.member<float>("x")
|
|
.member<float>("y");
|
|
|
|
flecs::entity e = ecs.entity();
|
|
|
|
const char *r = e.from_json("{\"path\":\"ent\"}");
|
|
test_str(r, "");
|
|
|
|
test_assert(e != 0);
|
|
test_str(e.name(), "ent");
|
|
}
|
|
|
|
void Meta_entity_from_json_w_ids(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<Position>()
|
|
.member<float>("x")
|
|
.member<float>("y");
|
|
|
|
flecs::entity e = ecs.entity();
|
|
|
|
const char *r = e.from_json("{\"path\":\"ent\", \"ids\":[[\"Position\"]]}");
|
|
test_str(r, "");
|
|
|
|
test_assert(e != 0);
|
|
test_str(e.name(), "ent");
|
|
test_assert(e.has<Position>());
|
|
}
|
|
|
|
void Meta_entity_from_json_w_values(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<Position>()
|
|
.member<float>("x")
|
|
.member<float>("y");
|
|
|
|
flecs::entity e = ecs.entity();
|
|
|
|
const char *r = e.from_json("{\"path\":\"ent\", \"ids\":[[\"Position\"]], \"values\":[{\"x\":10, \"y\":20}]}");
|
|
test_str(r, "");
|
|
|
|
test_assert(e != 0);
|
|
test_str(e.name(), "ent");
|
|
test_assert(e.has<Position>());
|
|
|
|
const Position *p = e.get<Position>();
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
}
|
|
|
|
void Meta_set_type_json(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<Position>()
|
|
.member<float>("x")
|
|
.member<float>("y");
|
|
|
|
flecs::entity e = ecs.entity()
|
|
.set_json<Position>("{\"x\":10, \"y\":20}");
|
|
|
|
const Position *p = e.get<Position>();
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
}
|
|
|
|
void Meta_set_pair_R_T_json(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<Position>()
|
|
.member<float>("x")
|
|
.member<float>("y");
|
|
|
|
flecs::entity e = ecs.entity()
|
|
.set_json<Position, Tag>("{\"x\":10, \"y\":20}");
|
|
|
|
const Position *p = e.get<Position, Tag>();
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
}
|
|
|
|
void Meta_set_pair_R_t_json(void) {
|
|
flecs::world ecs;
|
|
|
|
ecs.component<Position>()
|
|
.member<float>("x")
|
|
.member<float>("y");
|
|
|
|
flecs::entity tgt = ecs.entity();
|
|
|
|
flecs::entity e = ecs.entity()
|
|
.set_json<Position>(tgt, "{\"x\":10, \"y\":20}");
|
|
|
|
const Position *p = e.get<Position>(tgt);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
}
|
|
|
|
void Meta_set_pair_r_T_json(void) {
|
|
flecs::world ecs;
|
|
|
|
flecs::entity pos = ecs.component<Position>()
|
|
.member<float>("x")
|
|
.member<float>("y");
|
|
|
|
flecs::entity e = ecs.entity()
|
|
.set_json_second<Tag>(pos, "{\"x\":10, \"y\":20}");
|
|
|
|
const Position *p = e.get<Position, Tag>();
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
}
|
|
|
|
void Meta_set_pair_r_t_json(void) {
|
|
flecs::world ecs;
|
|
|
|
flecs::entity pos = ecs.component<Position>()
|
|
.member<float>("x")
|
|
.member<float>("y");
|
|
|
|
flecs::entity tgt = ecs.entity();
|
|
|
|
flecs::entity e = ecs.entity()
|
|
.set_json(pos, tgt, "{\"x\":10, \"y\":20}");
|
|
|
|
const Position *p = e.get<Position>(tgt);
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
}
|
|
|
|
void Meta_set_id_json(void) {
|
|
flecs::world ecs;
|
|
|
|
flecs::entity pos = ecs.component<Position>()
|
|
.member<float>("x")
|
|
.member<float>("y");
|
|
|
|
flecs::entity e = ecs.entity()
|
|
.set_json(pos, "{\"x\":10, \"y\":20}");
|
|
|
|
const Position *p = e.get<Position>();
|
|
test_assert(p != NULL);
|
|
test_int(p->x, 10);
|
|
test_int(p->y, 20);
|
|
}
|
|
|
|
void Meta_ser_deser_std_string(void) {
|
|
flecs::world world;
|
|
|
|
world.component<std::string>()
|
|
.opaque(std_string_support);
|
|
|
|
std::string v = "hello world";
|
|
test_str(world.to_json(&v).c_str(), "\"hello world\"");
|
|
|
|
world.from_json(&v, "\"foo bar\"");
|
|
test_str(world.to_json(&v).c_str(), "\"foo bar\"");
|
|
}
|
|
|
|
void Meta_ser_deser_std_vector_int(void) {
|
|
flecs::world world;
|
|
|
|
world.component<std::vector<int>>()
|
|
.opaque(std_vector_support<int>);
|
|
|
|
std::vector<int> v = {1, 2, 3};
|
|
test_str(world.to_json(&v).c_str(), "[1, 2, 3]");
|
|
|
|
world.from_json(&v, "[4, 5, 6]");
|
|
test_str(world.to_json(&v).c_str(), "[4, 5, 6]");
|
|
}
|
|
|
|
void Meta_ser_deser_std_vector_std_string(void) {
|
|
flecs::world world;
|
|
|
|
world.component<std::string>()
|
|
.opaque(std_string_support);
|
|
|
|
|
|
world.component<std::vector<std::string>>()
|
|
.opaque(std_vector_support<std::string>);
|
|
|
|
std::vector<std::string> v = {"foo", "bar"};
|
|
test_str(world.to_json(&v).c_str(), "[\"foo\", \"bar\"]");
|
|
|
|
world.from_json(&v, "[\"hello\", \"world\"]");
|
|
test_str(world.to_json(&v).c_str(), "[\"hello\", \"world\"]");
|
|
}
|
|
|
|
struct CppTypes {
|
|
std::string s;
|
|
std::vector<std::string> v;
|
|
};
|
|
|
|
void Meta_ser_deser_type_w_std_string_std_vector_std_string(void) {
|
|
flecs::world world;
|
|
|
|
world.component<std::string>()
|
|
.opaque(std_string_support);
|
|
|
|
world.component<std::vector<std::string>>()
|
|
.opaque(std_vector_support<std::string>);
|
|
|
|
world.component<CppTypes>()
|
|
.member<std::string>("s")
|
|
.member<std::vector<std::string>>("v");
|
|
|
|
CppTypes v = {"hello", {"world"}};
|
|
|
|
test_str(world.to_json(&v).c_str(), "{\"s\":\"hello\", \"v\":[\"world\"]}");
|
|
|
|
world.from_json(&v, "{\"s\":\"foo\", \"v\":[\"bar\"]}");
|
|
|
|
test_str(world.to_json(&v).c_str(), "{\"s\":\"foo\", \"v\":[\"bar\"]}");
|
|
}
|
|
|
|
void Meta_ser_deser_flecs_entity(void) {
|
|
flecs::world world;
|
|
|
|
flecs::entity e1 = world.entity("ent1");
|
|
flecs::entity e2 = world.entity("ent2");
|
|
|
|
flecs::entity v = e1;
|
|
test_str(world.to_json(&v).c_str(), "\"ent1\"");
|
|
|
|
world.from_json(&v, "\"ent2\"");
|
|
test_str(world.to_json(&v).c_str(), "\"ent2\"");
|
|
test_assert(v == e2);
|
|
}
|
|
|
|
struct CppEntity {
|
|
flecs::entity entity;
|
|
};
|
|
|
|
void Meta_world_ser_deser_flecs_entity(void) {
|
|
flecs::world world;
|
|
|
|
world.component<CppEntity>()
|
|
.member<flecs::entity>("entity");
|
|
|
|
flecs::entity e1 = world.entity("ent1");
|
|
flecs::entity e2 = world.entity("ent2").set<CppEntity>({e1});
|
|
|
|
{
|
|
const CppEntity *ptr = e2.get<CppEntity>();
|
|
test_assert(ptr != nullptr);
|
|
test_str(world.to_json(ptr).c_str(), "{\"entity\":\"ent1\"}");
|
|
}
|
|
|
|
auto json = world.to_json();
|
|
world.from_json(json);
|
|
|
|
test_assert(e1.is_alive());
|
|
test_assert(e2.is_alive());
|
|
|
|
{
|
|
const CppEntity *ptr = e2.get<CppEntity>();
|
|
test_assert(ptr != nullptr);
|
|
test_str(world.to_json(ptr).c_str(), "{\"entity\":\"ent1\"}");
|
|
}
|
|
}
|
|
|
|
void Meta_new_world_ser_deser_flecs_entity(void) {
|
|
flecs::world world;
|
|
|
|
world.component<CppEntity>()
|
|
.member<flecs::entity>("entity");
|
|
|
|
flecs::entity e1 = world.entity("ent1");
|
|
flecs::entity e2 = world.entity("ent2").set<CppEntity>({e1});
|
|
|
|
{
|
|
const CppEntity *ptr = e2.get<CppEntity>();
|
|
test_assert(ptr != nullptr);
|
|
test_str(world.to_json(ptr).c_str(), "{\"entity\":\"ent1\"}");
|
|
}
|
|
|
|
auto json = world.to_json();
|
|
|
|
flecs::world world2;
|
|
|
|
world2.component<CppEntity>()
|
|
.member<flecs::entity>("entity");
|
|
|
|
world2.from_json(json);
|
|
|
|
e1 = world2.lookup("ent1");
|
|
test_assert(e1 != 0);
|
|
e2 = world2.lookup("ent2");
|
|
test_assert(e2 != 0);
|
|
|
|
test_assert(e1.is_alive());
|
|
test_assert(e2.is_alive());
|
|
|
|
{
|
|
const CppEntity *ptr = e2.get<CppEntity>();
|
|
test_assert(ptr != nullptr);
|
|
test_str(world2.to_json(ptr).c_str(), "{\"entity\":\"ent1\"}");
|
|
}
|
|
}
|
|
|
|
void Meta_new_world_ser_deser_empty_flecs_entity(void) {
|
|
flecs::world world;
|
|
|
|
world.component<CppEntity>()
|
|
.member<flecs::entity>("entity");
|
|
|
|
flecs::entity e1 = world.entity("ent1").set<CppEntity>({});
|
|
|
|
{
|
|
const CppEntity *ptr = e1.get<CppEntity>();
|
|
test_assert(ptr != nullptr);
|
|
test_str(world.to_json(ptr).c_str(), "{\"entity\":0}");
|
|
}
|
|
|
|
auto json = world.to_json();
|
|
|
|
flecs::world world2;
|
|
|
|
world2.component<CppEntity>()
|
|
.member<flecs::entity>("entity");
|
|
|
|
world2.from_json(json);
|
|
|
|
e1 = world2.lookup("ent1");
|
|
test_assert(e1 != 0);
|
|
|
|
test_assert(e1.is_alive());
|
|
|
|
{
|
|
const CppEntity *ptr = e1.get<CppEntity>();
|
|
test_assert(ptr != nullptr);
|
|
test_str(world2.to_json(ptr).c_str(), "{\"entity\":0}");
|
|
}
|
|
}
|
|
|
|
void Meta_opaque_vector_w_builder(void) {
|
|
flecs::world world;
|
|
|
|
world.component<std::vector<int>>().opaque<int>(world.vector<int>())
|
|
.serialize([](const flecs::serializer *s, const std::vector<int> *data) {
|
|
for (const auto& el : *data) {
|
|
s->value(el);
|
|
}
|
|
return 0;
|
|
})
|
|
.count([](const std::vector<int> *data) {
|
|
return data->size();
|
|
})
|
|
.ensure_element([](std::vector<int> *data, size_t elem) {
|
|
if (data->size() <= elem) {
|
|
data->resize(elem + 1);
|
|
}
|
|
|
|
return &data->data()[elem];
|
|
})
|
|
.resize([](std::vector<int> *data, size_t size) {
|
|
data->resize(size);
|
|
});
|
|
|
|
std::vector<int> v = {};
|
|
|
|
world.from_json(&v, "[10, 20, 30]");
|
|
test_uint(v.size(), 3);
|
|
test_int(v[0], 10);
|
|
test_int(v[1], 20);
|
|
test_int(v[2], 30);
|
|
|
|
test_str(world.to_json(&v).c_str(), "[10, 20, 30]");
|
|
}
|
|
|
|
void Meta_deser_entity_w_path(void) {
|
|
flecs::world world;
|
|
|
|
flecs::entity ent = world.entity("ent");
|
|
|
|
flecs::entity e;
|
|
world.from_json(&e, "\"ent\"");
|
|
|
|
test_assert(e == ent);
|
|
test_str(e.path().c_str(), "::ent");
|
|
}
|
|
|
|
enum class EnumWithBits : uint32_t {
|
|
BitA = 0,
|
|
BitB = 1 << 0,
|
|
BitAll = 0xffffffff
|
|
};
|
|
|
|
struct EnumWithBitsStruct {
|
|
EnumWithBits bits = EnumWithBits::BitAll;
|
|
};
|
|
|
|
void Meta_enum_w_bits(void) {
|
|
flecs::world ecs;
|
|
|
|
flecs::log::set_level(-4);
|
|
|
|
/* It is illegal to register an enumeration as bitset, this test makes sure
|
|
* the code doesn't crash. */
|
|
ecs.component<EnumWithBits>()
|
|
.bit("BitA", (uint32_t)EnumWithBits::BitA)
|
|
.bit("BitB", (uint32_t)EnumWithBits::BitB)
|
|
.bit("BitAll", (uint32_t)EnumWithBits::BitAll);
|
|
|
|
ecs.component<EnumWithBitsStruct>()
|
|
.member<EnumWithBits>("bits");
|
|
|
|
for (int i = 0; i < 30; i++)
|
|
{
|
|
ecs.entity()
|
|
.child_of(ecs.entity())
|
|
.add<EnumWithBitsStruct>();
|
|
}
|
|
|
|
auto q = ecs.query<EnumWithBitsStruct>();
|
|
auto s = q.iter().to_json();
|
|
test_str(s.c_str(), "");
|
|
}
|
|
|
|
void Meta_value_range(void) {
|
|
flecs::world ecs;
|
|
|
|
flecs::entity s = ecs.component<Position>()
|
|
.member<float>("x").range(-1, 1)
|
|
.member<float>("y").range(-2, 2);
|
|
|
|
flecs::entity x = s.lookup("x");
|
|
test_assert(x != 0);
|
|
test_assert(x.has<flecs::MemberRanges>());
|
|
{
|
|
const flecs::MemberRanges *ranges = x.get<flecs::MemberRanges>();
|
|
test_assert(ranges != nullptr);
|
|
test_assert(ranges->value.min == -1);
|
|
test_assert(ranges->value.max == 1);
|
|
}
|
|
|
|
flecs::entity y = s.lookup("y");
|
|
test_assert(y != 0);
|
|
test_assert(y.has<flecs::MemberRanges>());
|
|
{
|
|
const flecs::MemberRanges *ranges = y.get<flecs::MemberRanges>();
|
|
test_assert(ranges != nullptr);
|
|
test_assert(ranges->value.min == -2);
|
|
test_assert(ranges->value.max == 2);
|
|
}
|
|
}
|
|
|
|
void Meta_warning_range(void) {
|
|
flecs::world ecs;
|
|
|
|
flecs::entity s = ecs.component<Position>()
|
|
.member<float>("x").warning_range(-1, 1)
|
|
.member<float>("y").warning_range(-2, 2);
|
|
|
|
flecs::entity x = s.lookup("x");
|
|
test_assert(x != 0);
|
|
test_assert(x.has<flecs::MemberRanges>());
|
|
{
|
|
const flecs::MemberRanges *ranges = x.get<flecs::MemberRanges>();
|
|
test_assert(ranges != nullptr);
|
|
test_assert(ranges->warning.min == -1);
|
|
test_assert(ranges->warning.max == 1);
|
|
}
|
|
|
|
flecs::entity y = s.lookup("y");
|
|
test_assert(y != 0);
|
|
test_assert(y.has<flecs::MemberRanges>());
|
|
{
|
|
const flecs::MemberRanges *ranges = y.get<flecs::MemberRanges>();
|
|
test_assert(ranges != nullptr);
|
|
test_assert(ranges->warning.min == -2);
|
|
test_assert(ranges->warning.max == 2);
|
|
}
|
|
}
|
|
|
|
void Meta_error_range(void) {
|
|
flecs::world ecs;
|
|
|
|
flecs::entity s = ecs.component<Position>()
|
|
.member<float>("x").error_range(-1, 1)
|
|
.member<float>("y").error_range(-2, 2);
|
|
|
|
flecs::entity x = s.lookup("x");
|
|
test_assert(x != 0);
|
|
test_assert(x.has<flecs::MemberRanges>());
|
|
{
|
|
const flecs::MemberRanges *ranges = x.get<flecs::MemberRanges>();
|
|
test_assert(ranges != nullptr);
|
|
test_assert(ranges->error.min == -1);
|
|
test_assert(ranges->error.max == 1);
|
|
}
|
|
|
|
flecs::entity y = s.lookup("y");
|
|
test_assert(y != 0);
|
|
test_assert(y.has<flecs::MemberRanges>());
|
|
{
|
|
const flecs::MemberRanges *ranges = y.get<flecs::MemberRanges>();
|
|
test_assert(ranges != nullptr);
|
|
test_assert(ranges->error.min == -2);
|
|
test_assert(ranges->error.max == 2);
|
|
}
|
|
}
|
|
|
|
void Meta_struct_member_ptr(void) {
|
|
flecs::world ecs;
|
|
|
|
struct Test {
|
|
int32_t x;
|
|
};
|
|
struct Test2 {
|
|
double y;
|
|
};
|
|
struct Nested {
|
|
Test a;
|
|
int pad; // This will be ignored
|
|
Test2 b[2];
|
|
};
|
|
|
|
auto t = ecs.component<Test>()
|
|
.member("x", &Test::x);
|
|
|
|
auto t2 = ecs.component<Test2>()
|
|
.member("y", &Test2::y);
|
|
|
|
auto n = ecs.component<Nested>()
|
|
.member("a", &Nested::a)
|
|
.member("b", &Nested::b);
|
|
|
|
{ // Validate Test
|
|
test_assert(t != 0);
|
|
|
|
auto x = t.lookup("x");
|
|
test_assert(x != 0);
|
|
test_assert(x.has<flecs::Member>());
|
|
const flecs::Member *xm = x.get<flecs::Member>();
|
|
test_uint(xm->type, flecs::I32);
|
|
test_uint(xm->offset, offsetof(Test, x));
|
|
}
|
|
{ // Validate Test2
|
|
test_assert(t2 != 0);
|
|
|
|
auto y = t2.lookup("y");
|
|
test_assert(y != 0);
|
|
test_assert(y.has<flecs::Member>());
|
|
const flecs::Member *ym = y.get<flecs::Member>();
|
|
test_uint(ym->type, flecs::F64);
|
|
test_uint(ym->offset, offsetof(Test2, y));
|
|
}
|
|
|
|
// Validate Nested
|
|
test_assert(n != 0);
|
|
{
|
|
auto a = n.lookup("a");
|
|
test_assert(a != 0);
|
|
test_assert(a.has<flecs::Member>());
|
|
const flecs::Member *am = a.get<flecs::Member>();
|
|
test_uint(am->type, t);
|
|
test_uint(am->offset, offsetof(Nested, a));
|
|
}
|
|
{
|
|
auto b = n.lookup("b");
|
|
test_assert(b != 0);
|
|
test_assert(b.has<flecs::Member>());
|
|
const flecs::Member *bm = b.get<flecs::Member>();
|
|
test_uint(bm->type, t2);
|
|
test_uint(bm->offset, offsetof(Nested, b));
|
|
test_uint(bm->count, 2);
|
|
}
|
|
}
|
|
|
|
void Meta_struct_member_ptr_packed_struct(void) {
|
|
flecs::world ecs;
|
|
|
|
#if defined(__GNUC__) || defined(__clang__)
|
|
struct PackedStruct {
|
|
char a;
|
|
int b;
|
|
char pad[2];
|
|
double c;
|
|
} __attribute__((__packed__));
|
|
#endif
|
|
|
|
#if defined(_MSC_VER)
|
|
#pragma pack(push, 1)
|
|
struct PackedStruct {
|
|
char a;
|
|
int b;
|
|
char pad[2];
|
|
double c;
|
|
};
|
|
#pragma pack(pop)
|
|
#endif
|
|
|
|
auto s = ecs.component<PackedStruct>()
|
|
.member("a", &PackedStruct::a)
|
|
.member("b", &PackedStruct::b)
|
|
.member("c", &PackedStruct::c);
|
|
|
|
test_assert(s != 0);
|
|
|
|
{
|
|
auto a = s.lookup("a");
|
|
test_assert(a != 0);
|
|
test_assert(a.has<flecs::Member>());
|
|
const flecs::Member *am = a.get<flecs::Member>();
|
|
test_uint(am->type, flecs::Char);
|
|
test_uint(am->offset, offsetof(PackedStruct, a));
|
|
}
|
|
{
|
|
auto b = s.lookup("b");
|
|
test_assert(b != 0);
|
|
test_assert(b.has<flecs::Member>());
|
|
const flecs::Member *bm = b.get<flecs::Member>();
|
|
test_uint(bm->type, flecs::I32);
|
|
test_uint(bm->offset, offsetof(PackedStruct, b));
|
|
}
|
|
{
|
|
auto c = s.lookup("c");
|
|
test_assert(c != 0);
|
|
test_assert(c.has<flecs::Member>());
|
|
const flecs::Member *cm = c.get<flecs::Member>();
|
|
test_uint(cm->type, flecs::F64);
|
|
test_uint(cm->offset, offsetof(PackedStruct, c));
|
|
}
|
|
}
|
|
|
|
void Meta_component_as_array(void) {
|
|
flecs::world ecs;
|
|
|
|
flecs::entity c = ecs.component<Position>()
|
|
.array<float>(2);
|
|
|
|
test_assert(c.has<flecs::Array>());
|
|
|
|
const flecs::Array *ptr = c.get<flecs::Array>();
|
|
test_assert(ptr != nullptr);
|
|
test_assert(ptr->type == ecs.id<float>());
|
|
test_int(ptr->count, 2);
|
|
}
|