registry: create no longer accepts a list of default constructible types to assign to entities
This commit is contained in:
2
TODO
2
TODO
@@ -13,9 +13,9 @@
|
||||
* static reflection, hint: template<> meta_type_t<Type>: meta_descriptor<name, func..., props..., etc...>
|
||||
* add meta support to registry (eg entity for each component and opaque get)
|
||||
* allow for custom stamp functions
|
||||
* merge create() and create(hint), is it a viable solution?
|
||||
* observer: user defined filters (eg .replace<T, &function> or .group<T, U, &func>)
|
||||
* use underlying_type as entity type within pools and registry? it would make different registries work together flawlessy
|
||||
* can we write a bool conv func for entt::entity that silently compares it to null?
|
||||
* stamp makes sense only when the list of components is empty
|
||||
* any-of rule for views/groups (eg entity has A and any of B/C/D)
|
||||
- get -> all, exclude -> none
|
||||
|
||||
@@ -172,10 +172,6 @@ auto view = registry.view<a_component, another_component>();
|
||||
registry.destroy(view.begin(), view.end());
|
||||
```
|
||||
|
||||
In all cases, the `create` member function accepts also a list of default
|
||||
constructible component types to assign to the entities before to return. It's a
|
||||
faster alternative to the creation and subsequent assignment of components.
|
||||
|
||||
When an entity is destroyed, the registry can freely reuse it internally with a
|
||||
slightly different identifier. In particular, the version of an entity is
|
||||
increased after destruction.<br/>
|
||||
|
||||
@@ -183,31 +183,6 @@ class basic_registry {
|
||||
}
|
||||
};
|
||||
|
||||
auto generate() {
|
||||
Entity entt;
|
||||
|
||||
if(destroyed == null) {
|
||||
entt = entities.emplace_back(entity_type(entities.size()));
|
||||
// traits_type::entity_mask is reserved to allow for null identifiers
|
||||
ENTT_ASSERT(to_integral(entt) < traits_type::entity_mask);
|
||||
} else {
|
||||
const auto curr = to_integral(destroyed);
|
||||
const auto version = to_integral(entities[curr]) & (traits_type::version_mask << traits_type::entity_shift);
|
||||
destroyed = entity_type{to_integral(entities[curr]) & traits_type::entity_mask};
|
||||
entt = entities[curr] = entity_type{curr | version};
|
||||
}
|
||||
|
||||
return entt;
|
||||
}
|
||||
|
||||
void release(const Entity entity) {
|
||||
// lengthens the implicit list of destroyed entities
|
||||
const auto entt = to_integral(entity) & traits_type::entity_mask;
|
||||
const auto version = ((to_integral(entity) >> traits_type::entity_shift) + 1) << traits_type::entity_shift;
|
||||
entities[entt] = entity_type{to_integral(destroyed) | version};
|
||||
destroyed = entity_type{entt};
|
||||
}
|
||||
|
||||
template<typename Component, typename... Args>
|
||||
const pool_handler<Component> & assure(Args &&... args) const {
|
||||
static std::size_t index{pools.size()};
|
||||
@@ -476,33 +451,28 @@ public:
|
||||
/**
|
||||
* @brief Creates a new entity and returns it.
|
||||
*
|
||||
* There are two kinds of entity identifiers:
|
||||
* There are two kinds of possible entity identifiers:
|
||||
*
|
||||
* * Newly created ones in case no entities have been previously destroyed.
|
||||
* * Recycled ones with updated versions.
|
||||
*
|
||||
* Users should not care about the type of the returned entity identifier.
|
||||
* In case entity identifers are stored around, the `valid` member
|
||||
* function can be used to know if they are still valid or the entity has
|
||||
* been destroyed and potentially recycled.<br/>
|
||||
* The returned entity has assigned the given components, if any.
|
||||
*
|
||||
* The components must be at least default constructible. A compilation
|
||||
* error will occur otherwhise.
|
||||
*
|
||||
* @tparam Component Types of components to assign to the entity.
|
||||
* @return A valid entity identifier if the component list is empty, a tuple
|
||||
* containing the entity identifier and the references to the components
|
||||
* just created otherwise.
|
||||
* @return A valid entity identifier.
|
||||
*/
|
||||
template<typename... Component>
|
||||
auto create() {
|
||||
if constexpr(sizeof...(Component) == 0) {
|
||||
return generate();
|
||||
entity_type create() {
|
||||
entity_type entt;
|
||||
|
||||
if(destroyed == null) {
|
||||
entt = entities.emplace_back(entity_type(entities.size()));
|
||||
// traits_type::entity_mask is reserved to allow for null identifiers
|
||||
ENTT_ASSERT(to_integral(entt) < traits_type::entity_mask);
|
||||
} else {
|
||||
const entity_type entt = generate();
|
||||
return std::tuple_cat(std::make_tuple(entt), std::forward_as_tuple(assign<Component>(entt)...));
|
||||
const auto curr = to_integral(destroyed);
|
||||
const auto version = to_integral(entities[curr]) & (traits_type::version_mask << traits_type::entity_shift);
|
||||
destroyed = entity_type{to_integral(entities[curr]) & traits_type::entity_mask};
|
||||
entt = entities[curr] = entity_type{curr | version};
|
||||
}
|
||||
|
||||
return entt;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -510,24 +480,13 @@ public:
|
||||
*
|
||||
* @sa create
|
||||
*
|
||||
* The components must be at least move and default insertable. A
|
||||
* compilation error will occur otherwhise.
|
||||
*
|
||||
* @tparam Component Types of components to assign to the entity.
|
||||
* @tparam It Type of forward iterator.
|
||||
* @param first An iterator to the first element of the range to generate.
|
||||
* @param last An iterator past the last element of the range to generate.
|
||||
* @return No return value if the component list is empty, a tuple
|
||||
* containing the iterators to the lists of components just created and
|
||||
* sorted the same of the entities otherwise.
|
||||
*/
|
||||
template<typename... Component, typename It>
|
||||
auto create(It first, It last) {
|
||||
std::generate(first, last, [this]() { return generate(); });
|
||||
|
||||
if constexpr(sizeof...(Component) > 0) {
|
||||
return std::make_tuple(assure<Component>().assign(*this, first, last)...);
|
||||
}
|
||||
template<typename It>
|
||||
void create(It first, It last) {
|
||||
std::generate(first, last, [this]() { return create(); });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -538,14 +497,11 @@ public:
|
||||
* If the requested entity isn't in use, the suggested identifier is created
|
||||
* and returned. Otherwise, a new one will be generated for this purpose.
|
||||
*
|
||||
* @tparam Component Types of components to assign to the entity.
|
||||
* @param hint A desired entity identifier.
|
||||
* @return A valid entity identifier if the component list is empty, a tuple
|
||||
* containing the entity identifier and the references to the components
|
||||
* just created otherwise.
|
||||
* @return A valid entity identifier.
|
||||
*/
|
||||
template<typename... Component>
|
||||
auto create(const entity_type hint) {
|
||||
entity_type create(const entity_type hint) {
|
||||
ENTT_ASSERT(hint != null);
|
||||
entity_type entt;
|
||||
|
||||
@@ -559,7 +515,7 @@ public:
|
||||
|
||||
entt = entities.emplace_back(hint);
|
||||
} else if(const auto curr = (to_integral(entities[req]) & traits_type::entity_mask); req == curr) {
|
||||
entt = generate();
|
||||
entt = create();
|
||||
} else {
|
||||
auto *it = &destroyed;
|
||||
for(; (to_integral(*it) & traits_type::entity_mask) != req; it = &entities[to_integral(*it) & traits_type::entity_mask]);
|
||||
@@ -567,20 +523,14 @@ public:
|
||||
entt = entities[req] = hint;
|
||||
}
|
||||
|
||||
if constexpr(sizeof...(Component) == 0) {
|
||||
return entt;
|
||||
} else {
|
||||
return std::tuple_cat(std::make_tuple(entt), std::forward_as_tuple(assign<Component>(entt)...));
|
||||
}
|
||||
return entt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destroys an entity and lets the registry recycle the identifier.
|
||||
*
|
||||
* When an entity is destroyed, its version is updated and the identifier
|
||||
* can be recycled at any time. In case entity identifers are stored around,
|
||||
* the `valid` member function can be used to know if they are still valid
|
||||
* or the entity has been destroyed and potentially recycled.
|
||||
* can be recycled at any time.
|
||||
*
|
||||
* @warning
|
||||
* In case there are listeners that observe the destruction of components
|
||||
@@ -607,7 +557,12 @@ public:
|
||||
|
||||
// just a way to protect users from listeners that attach components
|
||||
ENTT_ASSERT(orphan(entity));
|
||||
release(entity);
|
||||
|
||||
// lengthens the implicit list of destroyed entities
|
||||
const auto entt = to_integral(entity) & traits_type::entity_mask;
|
||||
const auto version = ((to_integral(entity) >> traits_type::entity_shift) + 1) << traits_type::entity_shift;
|
||||
entities[entt] = entity_type{to_integral(destroyed) | version};
|
||||
destroyed = entity_type{entt};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -658,10 +613,10 @@ public:
|
||||
*
|
||||
* @tparam Component Type of component to create.
|
||||
* @tparam It Type of input iterator.
|
||||
* @tparam Args Types of arguments to use to construct the component.
|
||||
* @tparam Args Types of arguments to use to construct the components.
|
||||
* @param first An iterator to the first element of the range of entities.
|
||||
* @param last An iterator past the last element of the range of entities.
|
||||
* @param args Parameters to use to initialize the component.
|
||||
* @param args Parameters to use to initialize the components.
|
||||
* @return An iterator to the list of components just created.
|
||||
*/
|
||||
template<typename Component, typename It, typename... Args>
|
||||
|
||||
@@ -114,7 +114,9 @@ TEST(Benchmark, ConstructManyWithComponents) {
|
||||
std::cout << "Constructing 1000000 entities at once with components" << std::endl;
|
||||
|
||||
timer timer;
|
||||
registry.create<position, velocity>(entities.begin(), entities.end());
|
||||
registry.create(entities.begin(), entities.end());
|
||||
registry.assign<position>(entities.begin(), entities.end());
|
||||
registry.assign<velocity>(entities.begin(), entities.end());
|
||||
timer.elapsed();
|
||||
}
|
||||
|
||||
|
||||
@@ -468,7 +468,11 @@ TEST(NonOwningGroup, TrackEntitiesOnComponentDestruction) {
|
||||
|
||||
TEST(NonOwningGroup, Less) {
|
||||
entt::registry registry;
|
||||
const auto entity = std::get<0>(registry.create<int, char, entt::tag<"empty"_hs>>());
|
||||
const auto entity = registry.create();
|
||||
|
||||
registry.assign<int>(entity);
|
||||
registry.assign<char>(entity);
|
||||
registry.assign<entt::tag<"empty"_hs>>(entity);
|
||||
|
||||
registry.group(entt::get<int, char, entt::tag<"empty"_hs>>).less([entity](const auto entt, int, char) {
|
||||
ASSERT_EQ(entity, entt);
|
||||
@@ -1040,7 +1044,11 @@ TEST(OwningGroup, TrackEntitiesOnComponentDestruction) {
|
||||
|
||||
TEST(OwningGroup, Less) {
|
||||
entt::registry registry;
|
||||
const auto entity = std::get<0>(registry.create<int, char, entt::tag<"empty"_hs>>());
|
||||
const auto entity = registry.create();
|
||||
|
||||
registry.assign<int>(entity);
|
||||
registry.assign<char>(entity);
|
||||
registry.assign<entt::tag<"empty"_hs>>(entity);
|
||||
|
||||
registry.group<int>(entt::get<char, entt::tag<"empty"_hs>>).less([entity](const auto entt, int, char) {
|
||||
ASSERT_EQ(entity, entt);
|
||||
|
||||
@@ -14,7 +14,8 @@ TEST(Observer, Functionalities) {
|
||||
ASSERT_EQ(observer.data(), nullptr);
|
||||
ASSERT_EQ(observer.begin(), observer.end());
|
||||
|
||||
const auto entity = std::get<0>(registry.create<int>());
|
||||
const auto entity = registry.create();
|
||||
registry.assign<int>(entity);
|
||||
|
||||
ASSERT_EQ(observer.size(), 1u);
|
||||
ASSERT_FALSE(observer.empty());
|
||||
@@ -263,7 +264,8 @@ TEST(Observer, CrossRulesCornerCase) {
|
||||
TEST(Observer, Each) {
|
||||
entt::registry registry;
|
||||
entt::observer observer{registry, entt::collector.group<int>()};
|
||||
const auto entity = std::get<0>(registry.create<int>());
|
||||
const auto entity = registry.create();
|
||||
registry.assign<int>(entity);
|
||||
|
||||
ASSERT_FALSE(observer.empty());
|
||||
ASSERT_EQ(observer.size(), 1u);
|
||||
|
||||
@@ -279,6 +279,93 @@ TEST(Registry, RawData) {
|
||||
ASSERT_EQ(*std::as_const(registry).data<int>(), entity);
|
||||
}
|
||||
|
||||
TEST(Registry, CreateManyEntitiesAtOnce) {
|
||||
entt::registry registry;
|
||||
entt::entity entities[3];
|
||||
|
||||
const auto entity = registry.create();
|
||||
registry.destroy(registry.create());
|
||||
registry.destroy(entity);
|
||||
registry.destroy(registry.create());
|
||||
|
||||
registry.create(std::begin(entities), std::end(entities));
|
||||
|
||||
ASSERT_TRUE(registry.valid(entities[0]));
|
||||
ASSERT_TRUE(registry.valid(entities[1]));
|
||||
ASSERT_TRUE(registry.valid(entities[2]));
|
||||
|
||||
ASSERT_EQ(registry.entity(entities[0]), entt::entity{0});
|
||||
ASSERT_EQ(registry.version(entities[0]), entt::registry::version_type{2});
|
||||
|
||||
ASSERT_EQ(registry.entity(entities[1]), entt::entity{1});
|
||||
ASSERT_EQ(registry.version(entities[1]), entt::registry::version_type{1});
|
||||
|
||||
ASSERT_EQ(registry.entity(entities[2]), entt::entity{2});
|
||||
ASSERT_EQ(registry.version(entities[2]), entt::registry::version_type{0});
|
||||
}
|
||||
|
||||
TEST(Registry, CreateWithHint) {
|
||||
entt::registry registry;
|
||||
auto e3 = registry.create(entt::entity{3});
|
||||
auto e2 = registry.create(entt::entity{3});
|
||||
|
||||
ASSERT_EQ(e2, entt::entity{2});
|
||||
ASSERT_FALSE(registry.valid(entt::entity{1}));
|
||||
ASSERT_EQ(e3, entt::entity{3});
|
||||
|
||||
registry.destroy(e2);
|
||||
|
||||
ASSERT_EQ(registry.version(e2), 0);
|
||||
ASSERT_EQ(registry.current(e2), 1);
|
||||
|
||||
e2 = registry.create();
|
||||
auto e1 = registry.create(entt::entity{2});
|
||||
|
||||
ASSERT_EQ(registry.entity(e2), entt::entity{2});
|
||||
ASSERT_EQ(registry.version(e2), 1);
|
||||
|
||||
ASSERT_EQ(registry.entity(e1), entt::entity{1});
|
||||
ASSERT_EQ(registry.version(e1), 0);
|
||||
|
||||
registry.destroy(e1);
|
||||
registry.destroy(e2);
|
||||
auto e0 = registry.create(entt::entity{0});
|
||||
|
||||
ASSERT_EQ(e0, entt::entity{0});
|
||||
ASSERT_EQ(registry.version(e0), 0);
|
||||
}
|
||||
|
||||
TEST(Registry, CreateDestroyEntities) {
|
||||
entt::registry registry;
|
||||
entt::entity pre{}, post{};
|
||||
|
||||
for(int i = 0; i < 10; ++i) {
|
||||
const auto entity = registry.create();
|
||||
registry.assign<double>(entity);
|
||||
}
|
||||
|
||||
registry.reset();
|
||||
|
||||
for(int i = 0; i < 7; ++i) {
|
||||
const auto entity = registry.create();
|
||||
registry.assign<int>(entity);
|
||||
if(i == 3) { pre = entity; }
|
||||
}
|
||||
|
||||
registry.reset();
|
||||
|
||||
for(int i = 0; i < 5; ++i) {
|
||||
const auto entity = registry.create();
|
||||
if(i == 3) { post = entity; }
|
||||
}
|
||||
|
||||
ASSERT_FALSE(registry.valid(pre));
|
||||
ASSERT_TRUE(registry.valid(post));
|
||||
ASSERT_NE(registry.version(pre), registry.version(post));
|
||||
ASSERT_EQ(registry.version(pre) + 1, registry.version(post));
|
||||
ASSERT_EQ(registry.current(pre), registry.current(post));
|
||||
}
|
||||
|
||||
TEST(Registry, CreateDestroyCornerCase) {
|
||||
entt::registry registry;
|
||||
|
||||
@@ -316,9 +403,9 @@ TEST(Registry, Each) {
|
||||
entt::registry::size_type match;
|
||||
|
||||
registry.create();
|
||||
registry.create<int>();
|
||||
registry.assign<int>(registry.create());
|
||||
registry.create();
|
||||
registry.create<int>();
|
||||
registry.assign<int>(registry.create());
|
||||
registry.create();
|
||||
|
||||
tot = 0u;
|
||||
@@ -367,9 +454,9 @@ TEST(Registry, Orphans) {
|
||||
entt::registry registry;
|
||||
entt::registry::size_type tot{};
|
||||
|
||||
registry.create<int>();
|
||||
registry.assign<int>(registry.create());
|
||||
registry.create();
|
||||
registry.create<int>();
|
||||
registry.assign<int>(registry.create());
|
||||
|
||||
registry.orphans([&](auto) { ++tot; });
|
||||
ASSERT_EQ(tot, 1u);
|
||||
@@ -385,37 +472,6 @@ TEST(Registry, Orphans) {
|
||||
ASSERT_EQ(tot, 0u);
|
||||
}
|
||||
|
||||
TEST(Registry, CreateDestroyEntities) {
|
||||
entt::registry registry;
|
||||
entt::entity pre{}, post{};
|
||||
|
||||
for(int i = 0; i < 10; ++i) {
|
||||
const auto entity = registry.create();
|
||||
registry.assign<double>(entity);
|
||||
}
|
||||
|
||||
registry.reset();
|
||||
|
||||
for(int i = 0; i < 7; ++i) {
|
||||
const auto entity = registry.create();
|
||||
registry.assign<int>(entity);
|
||||
if(i == 3) { pre = entity; }
|
||||
}
|
||||
|
||||
registry.reset();
|
||||
|
||||
for(int i = 0; i < 5; ++i) {
|
||||
const auto entity = registry.create();
|
||||
if(i == 3) { post = entity; }
|
||||
}
|
||||
|
||||
ASSERT_FALSE(registry.valid(pre));
|
||||
ASSERT_TRUE(registry.valid(post));
|
||||
ASSERT_NE(registry.version(pre), registry.version(post));
|
||||
ASSERT_EQ(registry.version(pre) + 1, registry.version(post));
|
||||
ASSERT_EQ(registry.current(pre), registry.current(post));
|
||||
}
|
||||
|
||||
TEST(Registry, View) {
|
||||
entt::registry registry;
|
||||
auto mview = registry.view<int, char>();
|
||||
@@ -444,10 +500,14 @@ TEST(Registry, View) {
|
||||
|
||||
TEST(Registry, NonOwningGroupInitOnFirstUse) {
|
||||
entt::registry registry;
|
||||
auto create = [&](auto... component) {
|
||||
const auto entity = registry.create();
|
||||
(registry.assign<decltype(component)>(entity, component), ...);
|
||||
};
|
||||
|
||||
std::get<2>(registry.create<int, char>()) = 'c';
|
||||
registry.create<int>();
|
||||
std::get<2>(registry.create<int, char>()) = 'c';
|
||||
create(0, 'c');
|
||||
create(0);
|
||||
create(0, 'c');
|
||||
|
||||
std::size_t cnt{};
|
||||
auto group = registry.group<>(entt::get<int, char>);
|
||||
@@ -460,10 +520,14 @@ TEST(Registry, NonOwningGroupInitOnFirstUse) {
|
||||
TEST(Registry, NonOwningGroupInitOnAssign) {
|
||||
entt::registry registry;
|
||||
auto group = registry.group<>(entt::get<int, char>);
|
||||
auto create = [&](auto... component) {
|
||||
const auto entity = registry.create();
|
||||
(registry.assign<decltype(component)>(entity, component), ...);
|
||||
};
|
||||
|
||||
std::get<2>(registry.create<int, char>()) = 'c';
|
||||
registry.create<int>();
|
||||
std::get<2>(registry.create<int, char>()) = 'c';
|
||||
create(0, 'c');
|
||||
create(0);
|
||||
create(0, 'c');
|
||||
|
||||
std::size_t cnt{};
|
||||
group.each([&cnt](auto...) { ++cnt; });
|
||||
@@ -474,10 +538,14 @@ TEST(Registry, NonOwningGroupInitOnAssign) {
|
||||
|
||||
TEST(Registry, FullOwningGroupInitOnFirstUse) {
|
||||
entt::registry registry;
|
||||
auto create = [&](auto... component) {
|
||||
const auto entity = registry.create();
|
||||
(registry.assign<decltype(component)>(entity, component), ...);
|
||||
};
|
||||
|
||||
std::get<2>(registry.create<int, char>()) = 'c';
|
||||
registry.create<int>();
|
||||
std::get<2>(registry.create<int, char>()) = 'c';
|
||||
create(0, 'c');
|
||||
create(0);
|
||||
create(0, 'c');
|
||||
|
||||
std::size_t cnt{};
|
||||
auto group = registry.group<int, char>();
|
||||
@@ -492,10 +560,14 @@ TEST(Registry, FullOwningGroupInitOnFirstUse) {
|
||||
TEST(Registry, FullOwningGroupInitOnAssign) {
|
||||
entt::registry registry;
|
||||
auto group = registry.group<int, char>();
|
||||
auto create = [&](auto... component) {
|
||||
const auto entity = registry.create();
|
||||
(registry.assign<decltype(component)>(entity, component), ...);
|
||||
};
|
||||
|
||||
std::get<2>(registry.create<int, char>()) = 'c';
|
||||
registry.create<int>();
|
||||
std::get<2>(registry.create<int, char>()) = 'c';
|
||||
create(0, 'c');
|
||||
create(0);
|
||||
create(0, 'c');
|
||||
|
||||
std::size_t cnt{};
|
||||
group.each([&cnt](auto...) { ++cnt; });
|
||||
@@ -508,10 +580,14 @@ TEST(Registry, FullOwningGroupInitOnAssign) {
|
||||
|
||||
TEST(Registry, PartialOwningGroupInitOnFirstUse) {
|
||||
entt::registry registry;
|
||||
auto create = [&](auto... component) {
|
||||
const auto entity = registry.create();
|
||||
(registry.assign<decltype(component)>(entity, component), ...);
|
||||
};
|
||||
|
||||
std::get<2>(registry.create<int, char>()) = 'c';
|
||||
registry.create<int>();
|
||||
std::get<2>(registry.create<int, char>()) = 'c';
|
||||
create(0, 'c');
|
||||
create(0);
|
||||
create(0, 'c');
|
||||
|
||||
std::size_t cnt{};
|
||||
auto group = registry.group<int>(entt::get<char>);
|
||||
@@ -527,10 +603,14 @@ TEST(Registry, PartialOwningGroupInitOnFirstUse) {
|
||||
TEST(Registry, PartialOwningGroupInitOnAssign) {
|
||||
entt::registry registry;
|
||||
auto group = registry.group<int>(entt::get<char>);
|
||||
auto create = [&](auto... component) {
|
||||
const auto entity = registry.create();
|
||||
(registry.assign<decltype(component)>(entity, component), ...);
|
||||
};
|
||||
|
||||
std::get<2>(registry.create<int, char>()) = 'c';
|
||||
registry.create<int>();
|
||||
std::get<2>(registry.create<int, char>()) = 'c';
|
||||
create(0, 'c');
|
||||
create(0);
|
||||
create(0, 'c');
|
||||
|
||||
std::size_t cnt{};
|
||||
group.each([&cnt](auto...) { ++cnt; });
|
||||
@@ -669,7 +749,9 @@ TEST(Registry, NestedGroups) {
|
||||
entt::registry registry;
|
||||
entt::entity entities[10];
|
||||
|
||||
registry.create<int, char>(std::begin(entities), std::end(entities));
|
||||
registry.create(std::begin(entities), std::end(entities));
|
||||
registry.assign<int>(std::begin(entities), std::end(entities));
|
||||
registry.assign<char>(std::begin(entities), std::end(entities));
|
||||
const auto g1 = registry.group<int>(entt::get<char>, entt::exclude<double>);
|
||||
|
||||
ASSERT_TRUE(g1.sortable());
|
||||
@@ -1118,152 +1200,6 @@ TEST(Registry, RangeRemove) {
|
||||
ASSERT_TRUE(registry.has<int>(e2));
|
||||
}
|
||||
|
||||
TEST(Registry, CreateManyEntitiesAtOnce) {
|
||||
entt::registry registry;
|
||||
entt::entity entities[3];
|
||||
|
||||
const auto entity = registry.create();
|
||||
registry.destroy(registry.create());
|
||||
registry.destroy(entity);
|
||||
registry.destroy(registry.create());
|
||||
|
||||
registry.create(std::begin(entities), std::end(entities));
|
||||
|
||||
ASSERT_TRUE(registry.valid(entities[0]));
|
||||
ASSERT_TRUE(registry.valid(entities[1]));
|
||||
ASSERT_TRUE(registry.valid(entities[2]));
|
||||
|
||||
ASSERT_EQ(registry.entity(entities[0]), entt::entity{0});
|
||||
ASSERT_EQ(registry.version(entities[0]), entt::registry::version_type{2});
|
||||
|
||||
ASSERT_EQ(registry.entity(entities[1]), entt::entity{1});
|
||||
ASSERT_EQ(registry.version(entities[1]), entt::registry::version_type{1});
|
||||
|
||||
ASSERT_EQ(registry.entity(entities[2]), entt::entity{2});
|
||||
ASSERT_EQ(registry.version(entities[2]), entt::registry::version_type{0});
|
||||
}
|
||||
|
||||
TEST(Registry, CreateAnEntityWithComponents) {
|
||||
entt::registry registry;
|
||||
auto &&[entity, ivalue, cvalue, evalue] = registry.create<int, char, empty_type>();
|
||||
// suppress warnings
|
||||
(void)evalue;
|
||||
|
||||
ASSERT_FALSE(registry.empty<int>());
|
||||
ASSERT_FALSE(registry.empty<char>());
|
||||
ASSERT_FALSE(registry.empty<empty_type>());
|
||||
|
||||
ASSERT_EQ(registry.size<int>(), entt::registry::size_type{1});
|
||||
ASSERT_EQ(registry.size<char>(), entt::registry::size_type{1});
|
||||
ASSERT_EQ(registry.size<empty_type>(), entt::registry::size_type{1});
|
||||
|
||||
ASSERT_TRUE((registry.has<int, char, empty_type>(entity)));
|
||||
|
||||
ivalue = 42;
|
||||
cvalue = 'c';
|
||||
|
||||
ASSERT_EQ(registry.get<int>(entity), 42);
|
||||
ASSERT_EQ(registry.get<char>(entity), 'c');
|
||||
}
|
||||
|
||||
TEST(Registry, CreateManyEntitiesWithComponentsAtOnce) {
|
||||
entt::registry registry;
|
||||
entt::entity entities[3];
|
||||
|
||||
const auto entity = registry.create();
|
||||
registry.destroy(registry.create());
|
||||
registry.destroy(entity);
|
||||
registry.destroy(registry.create());
|
||||
|
||||
const auto [iptr, cptr, eptr] = registry.create<int, char, empty_type>(std::begin(entities), std::end(entities));
|
||||
static_assert(std::is_same_v<typename decltype(eptr)::reference, empty_type>);
|
||||
|
||||
ASSERT_FALSE(registry.empty<int>());
|
||||
ASSERT_FALSE(registry.empty<char>());
|
||||
ASSERT_FALSE(registry.empty<empty_type>());
|
||||
|
||||
ASSERT_EQ(registry.size<int>(), entt::registry::size_type{3});
|
||||
ASSERT_EQ(registry.size<char>(), entt::registry::size_type{3});
|
||||
ASSERT_EQ(registry.size<empty_type>(), entt::registry::size_type{3});
|
||||
|
||||
ASSERT_TRUE(registry.valid(entities[0]));
|
||||
ASSERT_TRUE(registry.valid(entities[1]));
|
||||
ASSERT_TRUE(registry.valid(entities[2]));
|
||||
|
||||
ASSERT_EQ(registry.entity(entities[0]), entt::entity{0});
|
||||
ASSERT_EQ(registry.version(entities[0]), entt::registry::version_type{2});
|
||||
|
||||
ASSERT_EQ(registry.entity(entities[1]), entt::entity{1});
|
||||
ASSERT_EQ(registry.version(entities[1]), entt::registry::version_type{1});
|
||||
|
||||
ASSERT_EQ(registry.entity(entities[2]), entt::entity{2});
|
||||
ASSERT_EQ(registry.version(entities[2]), entt::registry::version_type{0});
|
||||
|
||||
ASSERT_TRUE((registry.has<int, char, empty_type>(entities[0])));
|
||||
ASSERT_TRUE((registry.has<int, char, empty_type>(entities[1])));
|
||||
ASSERT_TRUE((registry.has<int, char, empty_type>(entities[2])));
|
||||
|
||||
for(auto i = 0; i < 3; ++i) {
|
||||
iptr[i] = i;
|
||||
cptr[i] = char('a'+i);
|
||||
}
|
||||
|
||||
for(auto i = 0; i < 3; ++i) {
|
||||
ASSERT_EQ(registry.get<int>(entities[i]), i);
|
||||
ASSERT_EQ(registry.get<char>(entities[i]), char('a'+i));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Registry, CreateManyEntitiesWithComponentsAtOnceWithListener) {
|
||||
entt::registry registry;
|
||||
entt::entity entities[3];
|
||||
listener listener;
|
||||
|
||||
registry.on_construct<int>().connect<&listener::incr<int>>(listener);
|
||||
registry.create<int, char>(std::begin(entities), std::end(entities));
|
||||
|
||||
ASSERT_EQ(listener.counter, 3);
|
||||
|
||||
registry.on_construct<int>().disconnect<&listener::incr<int>>(listener);
|
||||
registry.on_construct<empty_type>().connect<&listener::incr<empty_type>>(listener);
|
||||
registry.create<char, empty_type>(std::begin(entities), std::end(entities));
|
||||
|
||||
ASSERT_EQ(listener.counter, 6);
|
||||
}
|
||||
|
||||
TEST(Registry, CreateWithHint) {
|
||||
entt::registry registry;
|
||||
auto e3 = registry.create(entt::entity{3});
|
||||
auto e2 = registry.create(entt::entity{3});
|
||||
|
||||
ASSERT_EQ(e2, entt::entity{2});
|
||||
ASSERT_FALSE(registry.valid(entt::entity{1}));
|
||||
ASSERT_EQ(e3, entt::entity{3});
|
||||
|
||||
registry.destroy(e2);
|
||||
|
||||
ASSERT_EQ(registry.version(e2), 0);
|
||||
ASSERT_EQ(registry.current(e2), 1);
|
||||
|
||||
e2 = registry.create();
|
||||
auto e1 = registry.create(entt::entity{2});
|
||||
|
||||
ASSERT_EQ(registry.entity(e2), entt::entity{2});
|
||||
ASSERT_EQ(registry.version(e2), 1);
|
||||
|
||||
ASSERT_EQ(registry.entity(e1), entt::entity{1});
|
||||
ASSERT_EQ(registry.version(e1), 0);
|
||||
|
||||
registry.destroy(e1);
|
||||
registry.destroy(e2);
|
||||
auto e0 = std::get<0>(registry.create<int>(entt::entity{0}));
|
||||
|
||||
ASSERT_EQ(e0, entt::entity{0});
|
||||
ASSERT_EQ(registry.version(e0), 0);
|
||||
ASSERT_TRUE(registry.has<int>(e0));
|
||||
ASSERT_FALSE(registry.has<char>(e0));
|
||||
}
|
||||
|
||||
TEST(Registry, NonOwningGroupInterleaved) {
|
||||
entt::registry registry;
|
||||
typename entt::entity entity = entt::null;
|
||||
|
||||
@@ -192,8 +192,14 @@ TEST(SingleComponentView, Find) {
|
||||
|
||||
TEST(SingleComponentView, Less) {
|
||||
entt::registry registry;
|
||||
const auto entity = std::get<0>(registry.create<int, entt::tag<"empty"_hs>>());
|
||||
registry.create<char>();
|
||||
auto create = [&](auto... component) {
|
||||
const auto entity = registry.create();
|
||||
(registry.assign<decltype(component)>(entity, component), ...);
|
||||
return entity;
|
||||
};
|
||||
|
||||
const auto entity = create(0, entt::tag<"empty"_hs>{});
|
||||
create('c');
|
||||
|
||||
registry.view<entt::tag<"empty"_hs>>().less([entity](const auto entt) {
|
||||
ASSERT_EQ(entity, entt);
|
||||
@@ -526,8 +532,16 @@ TEST(MultiComponentView, ExcludedComponents) {
|
||||
|
||||
TEST(MultiComponentView, Less) {
|
||||
entt::registry registry;
|
||||
const auto entity = std::get<0>(registry.create<int, char, double, entt::tag<"empty"_hs>>());
|
||||
registry.create<int, char>();
|
||||
|
||||
const auto entity = registry.create();
|
||||
registry.assign<int>(entity);
|
||||
registry.assign<char>(entity);
|
||||
registry.assign<double>(entity);
|
||||
registry.assign<entt::tag<"empty"_hs>>(entity);
|
||||
|
||||
const auto other = registry.create();
|
||||
registry.assign<int>(other);
|
||||
registry.assign<char>(other);
|
||||
|
||||
registry.view<int, char, entt::tag<"empty"_hs>>().less([entity](const auto entt, int, char) {
|
||||
ASSERT_EQ(entity, entt);
|
||||
|
||||
Reference in New Issue
Block a user