|
#ifndef ENTT_ENTITY_HELPER_HPP
|
|
#define ENTT_ENTITY_HELPER_HPP
|
|
|
|
#include <type_traits>
|
|
#include "../config/config.h"
|
|
#include "../core/fwd.hpp"
|
|
#include "../core/type_traits.hpp"
|
|
#include "../signal/delegate.hpp"
|
|
#include "fwd.hpp"
|
|
#include "registry.hpp"
|
|
|
|
namespace entt {
|
|
|
|
/**
|
|
* @brief Converts a registry to a view.
|
|
* @tparam Entity A valid entity type (see entt_traits for more details).
|
|
*/
|
|
template<typename Entity>
|
|
struct as_view {
|
|
/*! @brief Underlying entity identifier. */
|
|
using entity_type = std::remove_const_t<Entity>;
|
|
/*! @brief Type of registry to convert. */
|
|
using registry_type = constness_as_t<basic_registry<entity_type>, Entity>;
|
|
|
|
/**
|
|
* @brief Constructs a converter for a given registry.
|
|
* @param source A valid reference to a registry.
|
|
*/
|
|
as_view(registry_type &source) ENTT_NOEXCEPT: reg{source} {}
|
|
|
|
/**
|
|
* @brief Conversion function from a registry to a view.
|
|
* @tparam Exclude Types of components used to filter the view.
|
|
* @tparam Component Type of components used to construct the view.
|
|
* @return A newly created view.
|
|
*/
|
|
template<typename Exclude, typename... Component>
|
|
operator basic_view<entity_type, get_t<Component...>, Exclude>() const {
|
|
return reg.template view<Component...>(Exclude{});
|
|
}
|
|
|
|
private:
|
|
registry_type ®
|
|
};
|
|
|
|
/**
|
|
* @brief Deduction guide.
|
|
* @tparam Entity A valid entity type (see entt_traits for more details).
|
|
*/
|
|
template<typename Entity>
|
|
as_view(basic_registry<Entity> &) -> as_view<Entity>;
|
|
|
|
/**
|
|
* @brief Deduction guide.
|
|
* @tparam Entity A valid entity type (see entt_traits for more details).
|
|
*/
|
|
template<typename Entity>
|
|
as_view(const basic_registry<Entity> &) -> as_view<const Entity>;
|
|
|
|
/**
|
|
* @brief Converts a registry to a group.
|
|
* @tparam Entity A valid entity type (see entt_traits for more details).
|
|
*/
|
|
template<typename Entity>
|
|
struct as_group {
|
|
/*! @brief Underlying entity identifier. */
|
|
using entity_type = std::remove_const_t<Entity>;
|
|
/*! @brief Type of registry to convert. */
|
|
using registry_type = constness_as_t<basic_registry<entity_type>, Entity>;
|
|
|
|
/**
|
|
* @brief Constructs a converter for a given registry.
|
|
* @param source A valid reference to a registry.
|
|
*/
|
|
as_group(registry_type &source) ENTT_NOEXCEPT: reg{source} {}
|
|
|
|
/**
|
|
* @brief Conversion function from a registry to a group.
|
|
* @tparam Get Types of components observed by the group.
|
|
* @tparam Exclude Types of components used to filter the group.
|
|
* @tparam Owned Types of components owned by the group.
|
|
* @return A newly created group.
|
|
*/
|
|
template<typename Get, typename Exclude, typename... Owned>
|
|
operator basic_group<entity_type, owned_t<Owned...>, Get, Exclude>() const {
|
|
if constexpr(std::is_const_v<registry_type>) {
|
|
return reg.template group_if_exists<Owned...>(Get{}, Exclude{});
|
|
} else {
|
|
return reg.template group<Owned...>(Get{}, Exclude{});
|
|
}
|
|
}
|
|
|
|
private:
|
|
registry_type ®
|
|
};
|
|
|
|
/**
|
|
* @brief Deduction guide.
|
|
* @tparam Entity A valid entity type (see entt_traits for more details).
|
|
*/
|
|
template<typename Entity>
|
|
as_group(basic_registry<Entity> &) -> as_group<Entity>;
|
|
|
|
/**
|
|
* @brief Deduction guide.
|
|
* @tparam Entity A valid entity type (see entt_traits for more details).
|
|
*/
|
|
template<typename Entity>
|
|
as_group(const basic_registry<Entity> &) -> as_group<const Entity>;
|
|
|
|
/**
|
|
* @brief Helper to create a listener that directly invokes a member function.
|
|
* @tparam Member Member function to invoke on a component of the given type.
|
|
* @tparam Entity A valid entity type (see entt_traits for more details).
|
|
* @param reg A registry that contains the given entity and its components.
|
|
* @param entt Entity from which to get the component.
|
|
*/
|
|
template<auto Member, typename Entity = entity>
|
|
void invoke(basic_registry<Entity> ®, const Entity entt) {
|
|
static_assert(std::is_member_function_pointer_v<decltype(Member)>, "Invalid pointer to non-static member function");
|
|
delegate<void(basic_registry<Entity> &, const Entity)> func;
|
|
func.template connect<Member>(reg.template get<member_class_t<decltype(Member)>>(entt));
|
|
func(reg, entt);
|
|
}
|
|
|
|
/**
|
|
* @brief Returns the entity associated with a given component.
|
|
*
|
|
* @warning
|
|
* Currently, this function only works correctly with the default pool as it
|
|
* makes assumptions about how the components are laid out.
|
|
*
|
|
* @tparam Entity A valid entity type (see entt_traits for more details).
|
|
* @tparam Component Type of component.
|
|
* @param reg A registry that contains the given entity and its components.
|
|
* @param instance A valid component instance.
|
|
* @return The entity associated with the given component.
|
|
*/
|
|
template<typename Entity, typename Component>
|
|
Entity to_entity(const basic_registry<Entity> ®, const Component &instance) {
|
|
const auto &storage = reg.template storage<Component>();
|
|
const typename basic_registry<Entity>::base_type &base = storage;
|
|
const auto *addr = std::addressof(instance);
|
|
|
|
for(auto it = base.rbegin(), last = base.rend(); it < last; it += ENTT_PACKED_PAGE) {
|
|
if(const auto dist = (addr - std::addressof(storage.get(*it))); dist >= 0 && dist < ENTT_PACKED_PAGE) {
|
|
return *(it + dist);
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
} // namespace entt
|
|
|
|
#endif
|