Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
965c440d86 | ||
|
|
6b2aff821c | ||
|
|
84d9125ea1 | ||
|
|
9b969e762c | ||
|
|
2695d48ba7 | ||
|
|
aba2a6b17d | ||
|
|
7b87d17d22 |
1
AUTHORS
1
AUTHORS
@@ -11,6 +11,7 @@ ceeac
|
||||
ColinH
|
||||
corystegel
|
||||
Croydon
|
||||
cschreib
|
||||
cugone
|
||||
dbacchet
|
||||
dBagrat
|
||||
|
||||
7
TODO
7
TODO
@@ -8,16 +8,15 @@ EXAMPLES
|
||||
|
||||
WIP:
|
||||
* view/group: no storage_traits dependency -> use storage instead of components for the definition
|
||||
* resource<T>::operator</<=/>/>=
|
||||
* simplify emitter (see uvw), runtime events
|
||||
* basic_storage::bind for cross-registry setups
|
||||
* uses-allocator construction: any (with allocator support), poly, ...
|
||||
* process scheduler: reviews, use free lists internally
|
||||
* iterator based try_emplace vs try_insert for perf reasons
|
||||
* dedicated entity storage, in-place O(1) release/destroy for non-orphaned entities, out-of-sync model
|
||||
* entity-only and exclude-only views
|
||||
* custom allocators all over
|
||||
* use ENTT_NOEXCEPT_IF as appropriate (ie make compressed_pair conditionally noexcept)
|
||||
* custom allocators all over (sigh storage mixin, registry, ...)
|
||||
* consider removing ENTT_NOEXCEPT, use ENTT_NOEXCEPT_IF (or noexcept(...)) as appropriate in any case (ie make compressed_pair conditionally noexcept)
|
||||
* add test for maximum number of entities reached
|
||||
|
||||
WIP:
|
||||
* add user data to type_info
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,19 +4,22 @@
|
||||
#include "version.h"
|
||||
|
||||
#if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
|
||||
# define ENTT_NOEXCEPT noexcept
|
||||
# define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
|
||||
# define ENTT_THROW throw
|
||||
# define ENTT_TRY try
|
||||
# define ENTT_CATCH catch(...)
|
||||
#else
|
||||
# define ENTT_NOEXCEPT
|
||||
# define ENTT_NOEXCEPT_IF(...)
|
||||
# define ENTT_THROW
|
||||
# define ENTT_TRY if(true)
|
||||
# define ENTT_CATCH if(false)
|
||||
#endif
|
||||
|
||||
#ifndef ENTT_NOEXCEPT
|
||||
# define ENTT_NOEXCEPT noexcept
|
||||
# define ENTT_NOEXCEPT_IF(expr) noexcept(expr)
|
||||
# else
|
||||
# define ENTT_NOEXCEPT_IF(...)
|
||||
#endif
|
||||
|
||||
#ifdef ENTT_USE_ATOMIC
|
||||
# include <atomic>
|
||||
# define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#define ENTT_VERSION_MAJOR 3
|
||||
#define ENTT_VERSION_MINOR 10
|
||||
#define ENTT_VERSION_PATCH 0
|
||||
#define ENTT_VERSION_PATCH 1
|
||||
|
||||
#define ENTT_VERSION \
|
||||
ENTT_XSTR(ENTT_VERSION_MAJOR) \
|
||||
|
||||
@@ -302,7 +302,7 @@ class basic_registry {
|
||||
}
|
||||
|
||||
auto generate_identifier(const std::size_t pos) ENTT_NOEXCEPT {
|
||||
ENTT_ASSERT(pos < entity_traits::to_integral(null), "No entities available");
|
||||
ENTT_ASSERT(pos < entity_traits::to_entity(null), "No entities available");
|
||||
return entity_traits::combine(static_cast<typename entity_traits::entity_type>(pos), {});
|
||||
}
|
||||
|
||||
|
||||
@@ -55,14 +55,12 @@ struct basic_meta_sequence_container_traits {
|
||||
}
|
||||
|
||||
[[nodiscard]] static iterator iter(any &container, const bool as_end) {
|
||||
using std::begin;
|
||||
|
||||
if(auto *const cont = any_cast<Type>(&container); cont) {
|
||||
return iterator{begin(*cont), static_cast<typename iterator::difference_type>(as_end * cont->size())};
|
||||
return iterator{*cont, static_cast<typename iterator::difference_type>(as_end * cont->size())};
|
||||
}
|
||||
|
||||
const Type &as_const = any_cast<const Type &>(container);
|
||||
return iterator{begin(as_const), static_cast<typename iterator::difference_type>(as_end * as_const.size())};
|
||||
return iterator{as_const, static_cast<typename iterator::difference_type>(as_end * as_const.size())};
|
||||
}
|
||||
|
||||
[[nodiscard]] static iterator insert([[maybe_unused]] any &container, [[maybe_unused]] const std::ptrdiff_t offset, [[maybe_unused]] meta_any &value) {
|
||||
@@ -70,10 +68,9 @@ struct basic_meta_sequence_container_traits {
|
||||
if(auto *const cont = any_cast<Type>(&container); cont) {
|
||||
// this abomination is necessary because only on macos value_type and const_reference are different types for std::vector<bool>
|
||||
if(value.allow_cast<typename Type::const_reference>() || value.allow_cast<typename Type::value_type>()) {
|
||||
using std::begin;
|
||||
const auto *element = value.try_cast<std::remove_reference_t<typename Type::const_reference>>();
|
||||
const auto curr = cont->insert(begin(*cont) + offset, element ? *element : value.cast<typename Type::value_type>());
|
||||
return iterator{curr, curr - begin(*cont)};
|
||||
const auto curr = cont->insert(cont->begin() + offset, element ? *element : value.cast<typename Type::value_type>());
|
||||
return iterator{*cont, curr - cont->begin()};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,9 +81,8 @@ struct basic_meta_sequence_container_traits {
|
||||
[[nodiscard]] static iterator erase([[maybe_unused]] any &container, [[maybe_unused]] const std::ptrdiff_t offset) {
|
||||
if constexpr(is_dynamic_sequence_container<Type>::value) {
|
||||
if(auto *const cont = any_cast<Type>(&container); cont) {
|
||||
using std::begin;
|
||||
const auto curr = cont->erase(begin(*cont) + offset);
|
||||
return iterator{curr, curr - begin(*cont)};
|
||||
const auto curr = cont->erase(cont->begin() + offset);
|
||||
return iterator{*cont, curr - cont->begin()};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,15 +111,12 @@ struct basic_meta_associative_container_traits {
|
||||
}
|
||||
|
||||
[[nodiscard]] static iterator iter(any &container, const bool as_end) {
|
||||
using std::begin;
|
||||
using std::end;
|
||||
|
||||
if(auto *const cont = any_cast<Type>(&container); cont) {
|
||||
return iterator{std::integral_constant<bool, key_only>{}, as_end ? end(*cont) : begin(*cont)};
|
||||
return iterator{std::integral_constant<bool, key_only>{}, as_end ? cont->end() : cont->begin()};
|
||||
}
|
||||
|
||||
const auto &as_const = any_cast<const Type &>(container);
|
||||
return iterator{std::integral_constant<bool, key_only>{}, as_end ? end(as_const) : begin(as_const)};
|
||||
return iterator{std::integral_constant<bool, key_only>{}, as_end ? as_const.end() : as_const.begin()};
|
||||
}
|
||||
|
||||
[[nodiscard]] static bool insert(any &container, meta_any &key, [[maybe_unused]] meta_any &value) {
|
||||
|
||||
@@ -1070,6 +1070,15 @@ public:
|
||||
return !!(node->traits & internal::meta_traits::is_pointer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Provides the type for which the pointer is defined.
|
||||
* @return The type for which the pointer is defined or this type if it
|
||||
* doesn't refer to a pointer type.
|
||||
*/
|
||||
[[nodiscard]] meta_type remove_pointer() const ENTT_NOEXCEPT {
|
||||
return node->remove_pointer();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks whether a type is a pointer-like type or not.
|
||||
* @return True if the underlying type is a pointer-like one, false
|
||||
@@ -1464,11 +1473,11 @@ public:
|
||||
offset{},
|
||||
handle{} {}
|
||||
|
||||
template<typename It>
|
||||
explicit meta_iterator(It iter, const difference_type init) ENTT_NOEXCEPT
|
||||
: deref{&deref_fn<It>},
|
||||
template<typename Type>
|
||||
explicit meta_iterator(Type &cont, const difference_type init) ENTT_NOEXCEPT
|
||||
: deref{&deref_fn<decltype(cont.begin())>},
|
||||
offset{init},
|
||||
handle{std::move(iter)} {}
|
||||
handle{cont.begin()} {}
|
||||
|
||||
meta_iterator &operator++() ENTT_NOEXCEPT {
|
||||
return ++offset, *this;
|
||||
|
||||
@@ -108,6 +108,7 @@ struct meta_type_node {
|
||||
meta_type_node *next;
|
||||
meta_prop_node *prop;
|
||||
const size_type size_of;
|
||||
meta_type_node *(*const remove_pointer)() ENTT_NOEXCEPT;
|
||||
meta_any (*const default_constructor)();
|
||||
double (*const conversion_helper)(void *, const void *);
|
||||
const meta_template_node *const templ;
|
||||
@@ -180,6 +181,7 @@ public:
|
||||
nullptr,
|
||||
nullptr,
|
||||
size_of_v<Type>,
|
||||
&meta_node<std::remove_cv_t<std::remove_reference_t<std::remove_pointer_t<Type>>>>::resolve,
|
||||
meta_default_constructor(),
|
||||
meta_conversion_helper(),
|
||||
meta_template_info()
|
||||
|
||||
@@ -178,11 +178,65 @@ template<typename Res, typename Other>
|
||||
* @param rhs A valid handle.
|
||||
* @return False if both handles refer to the same registry, true otherwise.
|
||||
*/
|
||||
template<typename ILhs, typename IRhs>
|
||||
[[nodiscard]] bool operator!=(const resource<ILhs> &lhs, const resource<IRhs> &rhs) ENTT_NOEXCEPT {
|
||||
template<typename Res, typename Other>
|
||||
[[nodiscard]] bool operator!=(const resource<Res> &lhs, const resource<Other> &rhs) ENTT_NOEXCEPT {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compares two handles.
|
||||
* @tparam Res Type of resource managed by the first handle.
|
||||
* @tparam Other Type of resource managed by the second handle.
|
||||
* @param lhs A valid handle.
|
||||
* @param rhs A valid handle.
|
||||
* @return True if the first handle is less than the second, false otherwise.
|
||||
*/
|
||||
template<typename Res, typename Other>
|
||||
[[nodiscard]] bool operator<(const resource<Res> &lhs, const resource<Other> &rhs) ENTT_NOEXCEPT {
|
||||
return (std::addressof(*lhs) < std::addressof(*rhs));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compares two handles.
|
||||
* @tparam Res Type of resource managed by the first handle.
|
||||
* @tparam Other Type of resource managed by the second handle.
|
||||
* @param lhs A valid handle.
|
||||
* @param rhs A valid handle.
|
||||
* @return True if the first handle is greater than the second, false otherwise.
|
||||
*/
|
||||
template<typename Res, typename Other>
|
||||
[[nodiscard]] bool operator>(const resource<Res> &lhs, const resource<Other> &rhs) ENTT_NOEXCEPT {
|
||||
return (std::addressof(*lhs) > std::addressof(*rhs));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compares two handles.
|
||||
* @tparam Res Type of resource managed by the first handle.
|
||||
* @tparam Other Type of resource managed by the second handle.
|
||||
* @param lhs A valid handle.
|
||||
* @param rhs A valid handle.
|
||||
* @return True if the first handle is less than or equal to the second, false
|
||||
* otherwise.
|
||||
*/
|
||||
template<typename Res, typename Other>
|
||||
[[nodiscard]] bool operator<=(const resource<Res> &lhs, const resource<Other> &rhs) ENTT_NOEXCEPT {
|
||||
return !(lhs > rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compares two handles.
|
||||
* @tparam Res Type of resource managed by the first handle.
|
||||
* @tparam Other Type of resource managed by the second handle.
|
||||
* @param lhs A valid handle.
|
||||
* @param rhs A valid handle.
|
||||
* @return True if the first handle is greater than or equal to the second,
|
||||
* false otherwise.
|
||||
*/
|
||||
template<typename Res, typename Other>
|
||||
[[nodiscard]] bool operator>=(const resource<Res> &lhs, const resource<Other> &rhs) ENTT_NOEXCEPT {
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
} // namespace entt
|
||||
|
||||
#endif
|
||||
|
||||
@@ -147,11 +147,16 @@ TEST_F(MetaContainer, StdVector) {
|
||||
ASSERT_EQ(view.begin()->cast<int>(), 0);
|
||||
ASSERT_EQ((++view.begin())->cast<int>(), 1);
|
||||
|
||||
ret = view.insert(view.end(), 42);
|
||||
|
||||
ASSERT_TRUE(ret);
|
||||
ASSERT_EQ(*ret, 42);
|
||||
|
||||
it = view.begin();
|
||||
ret = view.erase(it);
|
||||
|
||||
ASSERT_TRUE(ret);
|
||||
ASSERT_EQ(view.size(), 4u);
|
||||
ASSERT_EQ(view.size(), 5u);
|
||||
ASSERT_EQ(ret->cast<int>(), 1);
|
||||
|
||||
ASSERT_TRUE(view.clear());
|
||||
|
||||
@@ -261,6 +261,13 @@ TEST_F(MetaType, Traits) {
|
||||
ASSERT_FALSE(entt::resolve<std::vector<int>>().is_associative_container());
|
||||
}
|
||||
|
||||
TEST_F(MetaType, RemovePointer) {
|
||||
ASSERT_EQ(entt::resolve<void *>().remove_pointer(), entt::resolve<void>());
|
||||
ASSERT_EQ(entt::resolve<char **>().remove_pointer(), entt::resolve<char *>());
|
||||
ASSERT_EQ(entt::resolve<int (*)(char, double)>().remove_pointer(), entt::resolve<int(char, double)>());
|
||||
ASSERT_EQ(entt::resolve<derived_t>().remove_pointer(), entt::resolve<derived_t>());
|
||||
}
|
||||
|
||||
TEST_F(MetaType, TemplateInfo) {
|
||||
ASSERT_FALSE(entt::resolve<int>().is_template_specialization());
|
||||
ASSERT_EQ(entt::resolve<int>().template_arity(), 0u);
|
||||
|
||||
@@ -128,3 +128,17 @@ TEST(Resource, DynamicResourceHandleCast) {
|
||||
ASSERT_FALSE(cast);
|
||||
ASSERT_EQ(resource.use_count(), 1u);
|
||||
}
|
||||
|
||||
TEST(Resource, Comparison) {
|
||||
entt::resource<derived> resource{std::make_shared<derived>()};
|
||||
entt::resource<const base> other = resource;
|
||||
|
||||
ASSERT_TRUE(resource == other);
|
||||
ASSERT_FALSE(resource != other);
|
||||
|
||||
ASSERT_FALSE(resource < other);
|
||||
ASSERT_FALSE(resource > other);
|
||||
|
||||
ASSERT_TRUE(resource <= other);
|
||||
ASSERT_TRUE(resource >= other);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user