added get_if where possible
This commit is contained in:
@@ -15,7 +15,6 @@
|
||||
* composable looper so as to pack erased systems, compose runners at different rates and run them at once in the loop
|
||||
* meta: sort of meta view based on meta stuff to iterate entities, void * and meta info objects
|
||||
* meta: move-to-head optimization when searching by name on parts (data, func, etc)
|
||||
* registry::probe<component>(entt) (returns a component * if entt has the component, nullptr otherwise)
|
||||
* hashed string: add implicit check on construction for uniqueness (optional)
|
||||
* add a note about multithreading support to the README file
|
||||
* signals on entity creation/destruction
|
||||
|
||||
+32
-12
@@ -120,23 +120,43 @@ struct actor {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a reference to the given component for an actor.
|
||||
* @tparam Component Type of the component to get.
|
||||
* @return A reference to the instance of the component owned by the actor.
|
||||
* @brief Returns references to the given components for an actor.
|
||||
* @tparam Component Types of components to get.
|
||||
* @return References to the components owned by the actor.
|
||||
*/
|
||||
template<typename Component>
|
||||
const Component & get() const ENTT_NOEXCEPT {
|
||||
return reg->template get<Component>(entt);
|
||||
template<typename... Component>
|
||||
decltype(auto) get() const ENTT_NOEXCEPT {
|
||||
return reg->template get<Component...>(entt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a reference to the given component for an actor.
|
||||
* @tparam Component Type of the component to get.
|
||||
* @return A reference to the instance of the component owned by the actor.
|
||||
* @brief Returns references to the given components for an actor.
|
||||
* @tparam Component Types of components to get.
|
||||
* @return References to the components owned by the actor.
|
||||
*/
|
||||
template<typename Component>
|
||||
inline Component & get() ENTT_NOEXCEPT {
|
||||
return const_cast<Component &>(std::as_const(*this).template get<Component>());
|
||||
template<typename... Component>
|
||||
decltype(auto) get() ENTT_NOEXCEPT {
|
||||
return reg->template get<Component...>(entt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns pointers to the given components for an actor.
|
||||
* @tparam Component Types of components to get.
|
||||
* @return Pointers to the components owned by the actor.
|
||||
*/
|
||||
template<typename... Component>
|
||||
auto get_if() const ENTT_NOEXCEPT {
|
||||
return reg->template get_if<Component...>(entt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns pointers to the given components for an actor.
|
||||
* @tparam Component Types of components to get.
|
||||
* @return Pointers to the components owned by the actor.
|
||||
*/
|
||||
template<typename... Component>
|
||||
auto get_if() ENTT_NOEXCEPT {
|
||||
return reg->template get_if<Component...>(entt);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -49,11 +49,6 @@ class prototype final {
|
||||
basic_fn_type *assign;
|
||||
};
|
||||
|
||||
template<typename Component>
|
||||
inline const Component & component() const ENTT_NOEXCEPT {
|
||||
return reg->template get<component_wrapper<Component>>(entity).component;
|
||||
}
|
||||
|
||||
void release() {
|
||||
if(reg->valid(entity)) {
|
||||
reg->destroy(entity);
|
||||
@@ -189,7 +184,8 @@ public:
|
||||
template<typename... Component>
|
||||
decltype(auto) get() const ENTT_NOEXCEPT {
|
||||
if constexpr(sizeof...(Component) == 1) {
|
||||
return component<Component...>();
|
||||
const auto &component = reg->template get<component_wrapper<Component...>>(entity).component;
|
||||
return component;
|
||||
} else {
|
||||
return std::tuple<const Component &...>{get<Component>()...};
|
||||
}
|
||||
@@ -216,6 +212,35 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns pointers to the given components.
|
||||
* @tparam Component Types of components to get.
|
||||
* @return Pointers to the components owned by the prototype.
|
||||
*/
|
||||
template<typename... Component>
|
||||
auto get_if() const ENTT_NOEXCEPT {
|
||||
if constexpr(sizeof...(Component) == 1) {
|
||||
const auto *wrapper = reg->template get_if<component_wrapper<Component...>>(entity);
|
||||
return wrapper ? &wrapper->component : nullptr;
|
||||
} else {
|
||||
return std::tuple<const Component *...>{get_if<Component>()...};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns pointers to the given components.
|
||||
* @tparam Component Types of components to get.
|
||||
* @return Pointers to the components owned by the prototype.
|
||||
*/
|
||||
template<typename... Component>
|
||||
inline auto get_if() ENTT_NOEXCEPT {
|
||||
if constexpr(sizeof...(Component) == 1) {
|
||||
return (const_cast<Component *>(std::as_const(*this).template get_if<Component>()), ...);
|
||||
} else {
|
||||
return std::tuple<Component *...>{get_if<Component>()...};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a new entity using a given prototype.
|
||||
*
|
||||
|
||||
@@ -624,6 +624,50 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns pointers to the given components for an entity.
|
||||
*
|
||||
* @warning
|
||||
* Attempting to use an invalid entity results in undefined behavior.<br/>
|
||||
* An assertion will abort the execution at runtime in debug mode in case of
|
||||
* invalid entity.
|
||||
*
|
||||
* @tparam Component Types of components to get.
|
||||
* @param entity A valid entity identifier.
|
||||
* @return Pointers to the components owned by the entity.
|
||||
*/
|
||||
template<typename... Component>
|
||||
auto get_if([[maybe_unused]] const entity_type entity) const ENTT_NOEXCEPT {
|
||||
assert(valid(entity));
|
||||
|
||||
if constexpr(sizeof...(Component) == 1) {
|
||||
return managed<Component...>() ? pool<Component...>().get_if(entity) : nullptr;
|
||||
} else {
|
||||
return std::tuple<const Component *...>{get_if<Component>(entity)...};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns pointers to the given components for an entity.
|
||||
*
|
||||
* @warning
|
||||
* Attempting to use an invalid entity results in undefined behavior.<br/>
|
||||
* An assertion will abort the execution at runtime in debug mode in case of
|
||||
* invalid entity.
|
||||
*
|
||||
* @tparam Component Types of components to get.
|
||||
* @param entity A valid entity identifier.
|
||||
* @return Pointers to the components owned by the entity.
|
||||
*/
|
||||
template<typename... Component>
|
||||
inline auto get_if([[maybe_unused]] const entity_type entity) ENTT_NOEXCEPT {
|
||||
if constexpr(sizeof...(Component) == 1) {
|
||||
return (const_cast<Component *>(std::as_const(*this).template get_if<Component>(entity)), ...);
|
||||
} else {
|
||||
return std::tuple<Component *...>{get_if<Component>(entity)...};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Replaces the given component for an entity.
|
||||
*
|
||||
|
||||
@@ -683,7 +683,7 @@ class sparse_set<Entity, Type>: public sparse_set<Entity> {
|
||||
};
|
||||
|
||||
public:
|
||||
/*! @brief Type of the objects associated to the entities. */
|
||||
/*! @brief Type of the objects associated with the entities. */
|
||||
using object_type = Type;
|
||||
/*! @brief Underlying entity identifier. */
|
||||
using entity_type = typename underlying_type::entity_type;
|
||||
@@ -881,7 +881,7 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the object associated to an entity.
|
||||
* @brief Returns the object associated with an entity.
|
||||
*
|
||||
* @warning
|
||||
* Attempting to use an entity that doesn't belong to the sparse set results
|
||||
@@ -890,14 +890,14 @@ public:
|
||||
* sparse set doesn't contain the given entity.
|
||||
*
|
||||
* @param entity A valid entity identifier.
|
||||
* @return The object associated to the entity.
|
||||
* @return The object associated with the entity.
|
||||
*/
|
||||
const object_type & get(const entity_type entity) const ENTT_NOEXCEPT {
|
||||
return instances[underlying_type::get(entity)];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the object associated to an entity.
|
||||
* @brief Returns the object associated with an entity.
|
||||
*
|
||||
* @warning
|
||||
* Attempting to use an entity that doesn't belong to the sparse set results
|
||||
@@ -906,12 +906,30 @@ public:
|
||||
* sparse set doesn't contain the given entity.
|
||||
*
|
||||
* @param entity A valid entity identifier.
|
||||
* @return The object associated to the entity.
|
||||
* @return The object associated with the entity.
|
||||
*/
|
||||
inline object_type & get(const entity_type entity) ENTT_NOEXCEPT {
|
||||
return const_cast<object_type &>(std::as_const(*this).get(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a pointer to the object associated with an entity, if any.
|
||||
* @param entity A valid entity identifier.
|
||||
* @return The object associated with the entity, if any.
|
||||
*/
|
||||
const object_type * get_if(const entity_type entity) const ENTT_NOEXCEPT {
|
||||
return underlying_type::has(entity) ? (instances.data() + underlying_type::get(entity)) : nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a pointer to the object associated with an entity, if any.
|
||||
* @param entity A valid entity identifier.
|
||||
* @return The object associated with the entity, if any.
|
||||
*/
|
||||
inline object_type * get_if(const entity_type entity) ENTT_NOEXCEPT {
|
||||
return const_cast<object_type *>(std::as_const(*this).get_if(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assigns an entity to a sparse set and constructs its object.
|
||||
*
|
||||
@@ -929,7 +947,7 @@ public:
|
||||
* @tparam Args Types of arguments to use to construct the object.
|
||||
* @param entity A valid entity identifier.
|
||||
* @param args Parameters to use to construct an object for the entity.
|
||||
* @return The object associated to the entity.
|
||||
* @return The object associated with the entity.
|
||||
*/
|
||||
template<typename... Args>
|
||||
object_type & construct(const entity_type entity, Args &&... args) {
|
||||
|
||||
+25
-15
@@ -3,8 +3,6 @@
|
||||
#include <entt/entity/actor.hpp>
|
||||
#include <entt/entity/registry.hpp>
|
||||
|
||||
struct actor_component final {};
|
||||
|
||||
TEST(Actor, Component) {
|
||||
entt::registry<> registry;
|
||||
entt::actor actor{registry};
|
||||
@@ -12,31 +10,43 @@ TEST(Actor, Component) {
|
||||
|
||||
ASSERT_EQ(®istry, &actor.backend());
|
||||
ASSERT_EQ(®istry, &cactor.backend());
|
||||
ASSERT_TRUE(registry.empty<actor_component>());
|
||||
ASSERT_TRUE(registry.empty<int>());
|
||||
ASSERT_FALSE(registry.empty());
|
||||
ASSERT_FALSE(actor.has<actor_component>());
|
||||
ASSERT_FALSE(actor.has<int>());
|
||||
|
||||
const auto &component = actor.assign<actor_component>();
|
||||
const auto &cint = actor.assign<int>();
|
||||
const auto &cchar = actor.assign<char>();
|
||||
|
||||
ASSERT_EQ(&component, &actor.get<actor_component>());
|
||||
ASSERT_EQ(&component, &cactor.get<actor_component>());
|
||||
ASSERT_FALSE(registry.empty<actor_component>());
|
||||
ASSERT_EQ(&cint, &actor.get<int>());
|
||||
ASSERT_EQ(&cchar, &cactor.get<char>());
|
||||
ASSERT_EQ(&cint, &std::get<0>(actor.get<int, char>()));
|
||||
ASSERT_EQ(&cchar, &std::get<1>(actor.get<int, char>()));
|
||||
ASSERT_EQ(&cint, std::get<0>(actor.get_if<int, char, double>()));
|
||||
ASSERT_EQ(&cchar, std::get<1>(actor.get_if<int, char, double>()));
|
||||
ASSERT_EQ(nullptr, std::get<2>(actor.get_if<int, char, double>()));
|
||||
ASSERT_EQ(nullptr, actor.get_if<double>());
|
||||
ASSERT_EQ(&cchar, actor.get_if<char>());
|
||||
ASSERT_EQ(&cint, actor.get_if<int>());
|
||||
|
||||
ASSERT_FALSE(registry.empty<int>());
|
||||
ASSERT_FALSE(registry.empty());
|
||||
ASSERT_TRUE(actor.has<actor_component>());
|
||||
ASSERT_TRUE(actor.has<int>());
|
||||
ASSERT_TRUE(actor.has<char>());
|
||||
ASSERT_FALSE(actor.has<double>());
|
||||
|
||||
actor.remove<actor_component>();
|
||||
actor.remove<int>();
|
||||
|
||||
ASSERT_TRUE(registry.empty<actor_component>());
|
||||
ASSERT_TRUE(registry.empty<int>());
|
||||
ASSERT_FALSE(registry.empty());
|
||||
ASSERT_FALSE(actor.has<actor_component>());
|
||||
ASSERT_FALSE(actor.has<int>());
|
||||
}
|
||||
|
||||
TEST(Actor, EntityLifetime) {
|
||||
entt::registry<> registry;
|
||||
auto *actor = new entt::actor{registry};
|
||||
actor->assign<actor_component>();
|
||||
actor->assign<int>();
|
||||
|
||||
ASSERT_FALSE(registry.empty<actor_component>());
|
||||
ASSERT_FALSE(registry.empty<int>());
|
||||
ASSERT_FALSE(registry.empty());
|
||||
|
||||
registry.each([actor](const auto entity) {
|
||||
@@ -45,6 +55,6 @@ TEST(Actor, EntityLifetime) {
|
||||
|
||||
delete actor;
|
||||
|
||||
ASSERT_TRUE(registry.empty<actor_component>());
|
||||
ASSERT_TRUE(registry.empty<int>());
|
||||
ASSERT_TRUE(registry.empty());
|
||||
}
|
||||
|
||||
@@ -21,6 +21,14 @@ TEST(Prototype, SameRegistry) {
|
||||
ASSERT_EQ(std::get<0>(prototype.get<int, char>()), 3);
|
||||
ASSERT_EQ(std::get<1>(cprototype.get<int, char>()), 'c');
|
||||
|
||||
ASSERT_NE(prototype.get_if<int>(), nullptr);
|
||||
ASSERT_NE(prototype.get_if<char>(), nullptr);
|
||||
ASSERT_EQ(prototype.get_if<double>(), nullptr);
|
||||
ASSERT_EQ(*prototype.get_if<int>(), 3);
|
||||
ASSERT_EQ(*cprototype.get_if<char>(), 'c');
|
||||
ASSERT_EQ(*std::get<0>(prototype.get_if<int, char, double>()), 3);
|
||||
ASSERT_EQ(*std::get<1>(cprototype.get_if<int, char, double>()), 'c');
|
||||
|
||||
const auto e0 = prototype.create();
|
||||
|
||||
ASSERT_TRUE((prototype.has<int, char>()));
|
||||
|
||||
@@ -74,6 +74,13 @@ TEST(Registry, Functionalities) {
|
||||
ASSERT_FALSE((registry.has<int, char>(e0)));
|
||||
ASSERT_TRUE((registry.has<int, char>(e1)));
|
||||
|
||||
ASSERT_EQ(registry.get_if<int>(e0), nullptr);
|
||||
ASSERT_NE(registry.get_if<int>(e1), nullptr);
|
||||
ASSERT_EQ(registry.get_if<char>(e0), nullptr);
|
||||
ASSERT_NE(registry.get_if<char>(e1), nullptr);
|
||||
ASSERT_EQ(registry.get_if<double>(e0), nullptr);
|
||||
ASSERT_EQ(registry.get_if<double>(e1), nullptr);
|
||||
|
||||
ASSERT_EQ(registry.assign<int>(e0, 42), 42);
|
||||
ASSERT_EQ(registry.assign<char>(e0, 'c'), 'c');
|
||||
ASSERT_NO_THROW(registry.remove<int>(e1));
|
||||
@@ -96,8 +103,16 @@ TEST(Registry, Functionalities) {
|
||||
ASSERT_EQ(registry.get<int>(e0), 42);
|
||||
ASSERT_EQ(registry.get<char>(e0), 'c');
|
||||
|
||||
ASSERT_NE(registry.get_if<int>(e0), nullptr);
|
||||
ASSERT_NE(registry.get_if<char>(e0), nullptr);
|
||||
ASSERT_EQ(registry.get_if<double>(e0), nullptr);
|
||||
ASSERT_EQ(*registry.get_if<int>(e0), 42);
|
||||
ASSERT_EQ(*registry.get_if<char>(e0), 'c');
|
||||
|
||||
ASSERT_EQ(std::get<0>(registry.get<int, char>(e0)), 42);
|
||||
ASSERT_EQ(*std::get<0>(registry.get_if<int, char, double>(e0)), 42);
|
||||
ASSERT_EQ(std::get<1>(static_cast<const entt::registry<> &>(registry).get<int, char>(e0)), 'c');
|
||||
ASSERT_EQ(*std::get<1>(static_cast<const entt::registry<> &>(registry).get_if<int, char, double>(e0)), 'c');
|
||||
|
||||
ASSERT_EQ(registry.get<int>(e0), registry.get<int>(e2));
|
||||
ASSERT_EQ(registry.get<char>(e0), registry.get<char>(e2));
|
||||
|
||||
Reference in New Issue
Block a user