diff --git a/TODO b/TODO index 43469c5a5..629edac71 100644 --- a/TODO +++ b/TODO @@ -20,4 +20,3 @@ - non-owning groups can iterate pages and skip empty ones, this should mitigate the lack of the packed array * review 64 bit id: user defined area + dedicated member on the registry to set it * reactive systems -* optimize groups access in case there are no named types (use family for direct access) diff --git a/src/entt/entity/registry.hpp b/src/entt/entity/registry.hpp index 73b804bea..52dafe1e2 100644 --- a/src/entt/entity/registry.hpp +++ b/src/entt/entity/registry.hpp @@ -191,18 +191,16 @@ class basic_registry { }; struct owning_group_data { + const std::size_t extent[3]; std::unique_ptr data; - bool(* exclude)(ENTT_ID_TYPE); - bool(* get)(ENTT_ID_TYPE); - bool(* owned)(ENTT_ID_TYPE); - std::size_t extent; + bool(* const is_same)(const ENTT_ID_TYPE *); + bool(* const owned)(ENTT_ID_TYPE); }; struct non_owning_group_data { + const std::size_t extent[2]; std::unique_ptr> data; - bool(* exclude)(ENTT_ID_TYPE); - bool(* get)(ENTT_ID_TYPE); - std::size_t extent; + bool(* const is_same)(const ENTT_ID_TYPE *); }; struct ctx_wrapper { @@ -297,21 +295,25 @@ class basic_registry { static_assert(sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude) > 1); static_assert(sizeof...(Owned) + sizeof...(Get) > 0); + const std::size_t extent[] = { sizeof...(Owned), sizeof...(Get), sizeof...(Exclude) }; + const ENTT_ID_TYPE types[] = { type()..., type()..., type()... }; + if constexpr(sizeof...(Owned) == 0) { - auto it = std::find_if(outer_groups.begin(), outer_groups.end(), [](auto &&gdata) { - return gdata.extent == sizeof...(Get) + sizeof...(Exclude) - && (gdata.exclude(type()) && ...) - && (gdata.get(type()) && ...); + auto it = std::find_if(outer_groups.begin(), outer_groups.end(), [&extent, &types](auto &&gdata) { + return std::equal(std::begin(extent), std::end(extent), gdata.extent) && gdata.is_same(types); }); if(it == outer_groups.cend()) { using group_type = non_owning_group, type_list>; - auto &gdata = outer_groups.emplace_back(); - gdata.data = std::make_unique(); - gdata.exclude = +[](component_type ctype) { return ((ctype == type()) || ...); }; - gdata.get = +[](component_type ctype) { return ((ctype == type()) || ...); }; - gdata.extent = sizeof...(Get) + sizeof...(Exclude); + non_owning_group_data gdata{ + { sizeof...(Get), sizeof...(Exclude) }, + std::make_unique(), + +[](const ENTT_ID_TYPE *other) { + const std::size_t types[] = { type()..., type()... }; + return std::equal(std::begin(types), std::end(types), other); + } + }; auto *curr = static_cast(gdata.data.get()); const auto cpools = std::make_tuple(assure()..., assure()...); @@ -328,28 +330,31 @@ class basic_registry { } } + outer_groups.push_back(std::move(gdata)); it = std::prev(outer_groups.end()); } return it->data.get(); } else { - auto it = std::find_if(inner_groups.begin(), inner_groups.end(), [](auto &&gdata) { - return gdata.extent == sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude) - && (gdata.exclude(type()) && ...) - && (gdata.get(type()) && ...) - && (gdata.owned(type()) && ...); + auto it = std::find_if(inner_groups.begin(), inner_groups.end(), [&extent, &types](auto &&gdata) { + return std::equal(std::begin(extent), std::end(extent), gdata.extent) && gdata.is_same(types); }); if(it == inner_groups.cend()) { ENTT_ASSERT(!(owned() || ...)); using group_type = owning_group, type_list, Owned...>; - auto &gdata = inner_groups.emplace_back(); - gdata.data = std::make_unique(); - gdata.exclude = +[](component_type ctype) { return ((ctype == type()) || ...); }; - gdata.get = +[](component_type ctype) { return ((ctype == type()) || ...); }; - gdata.owned = +[](component_type ctype) { return ((ctype == type()) || ...); }; - gdata.extent = sizeof...(Get) + sizeof...(Exclude) + sizeof...(Owned); + owning_group_data gdata{ + { sizeof...(Owned), sizeof...(Get), sizeof...(Exclude) }, + std::make_unique(), + +[](const ENTT_ID_TYPE *other) { + const std::size_t types[] = { type()..., type()..., type()... }; + return std::equal(std::begin(types), std::end(types), other); + }, + +[](ENTT_ID_TYPE ctype) { + return ((ctype == type()) || ...); + } + }; auto *curr = static_cast(gdata.data.get()); const auto cpools = std::make_tuple(assure()..., assure()..., assure()...); @@ -379,6 +384,7 @@ class basic_registry { } }); + inner_groups.push_back(std::move(gdata)); it = std::prev(inner_groups.end()); }