From 02b29af95a29a72a2efbc9a82041153711461265 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Sat, 24 Jul 2021 11:14:39 +0300 Subject: [PATCH] Introduce util::ecs::behavior::context --- libs/util/include/psemek/util/ecs.hpp | 68 +++++++++++++++++---------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/libs/util/include/psemek/util/ecs.hpp b/libs/util/include/psemek/util/ecs.hpp index dc0dff52..04b81abf 100644 --- a/libs/util/include/psemek/util/ecs.hpp +++ b/libs/util/include/psemek/util/ecs.hpp @@ -23,7 +23,12 @@ namespace psemek::util struct species_base { - virtual std::string_view name() const = 0; + species_base(std::string name, handle id) + : name_(std::move(name)) + , id_(id) + {} + + std::string_view name() const { return name_; } virtual void * get_species_component(std::type_index component_type) = 0; virtual void * get_entity_component(std::type_index component_type) = 0; @@ -65,6 +70,9 @@ namespace psemek::util private: + std::string name_; + handle id_; + template void apply_impl(Behavior & behavior, std::tuple *, std::index_sequence) { @@ -80,15 +88,16 @@ namespace psemek::util if (!std::apply(all_nonzero, cptrs)) return; - std::tuple cs; + typename Behavior::context ctx; + ctx.species = id_; - ((std::get(cs) = get_species_component()), ...); + ((std::get(ctx.components) = get_species_component()), ...); auto visit = [&](auto * ... ptrs) { - if constexpr (std::is_invocable_v const &>) + if constexpr (std::is_invocable_v) { - behavior(*ptrs..., cs); + behavior(*ptrs..., ctx); } else { @@ -108,7 +117,10 @@ namespace psemek::util for (std::size_t i = 0; i < count; ++i) { if (*list == i) + { + ctx.entity = i; std::apply(visit, cptrs); + } std::apply(increment, cptrs); ++list; } @@ -119,16 +131,11 @@ namespace psemek::util struct species_impl : species_base { - species_impl(std::string name, Components && ... components) - : name_(std::move(name)) + species_impl(std::string name, handle id, Components && ... components) + : species_base(std::move(name), id) , species_components_{std::move(components)...} {} - std::string_view name() const override - { - return name_; - } - using species_base::get_species_component; using species_base::get_entity_component; @@ -170,7 +177,6 @@ namespace psemek::util } private: - std::string name_; std::tuple species_components_; std::tuple...> entity_components_; std::vector list_; @@ -220,12 +226,6 @@ namespace psemek::util } }; - template - using prepare_helper = decltype(std::declval().prepare()); - - template - using has_prepare = std::experimental::is_detected; - } struct ecs @@ -235,6 +235,20 @@ namespace psemek::util { using component_types = std::tuple; using component_ptrs = std::tuple; + + struct context + { + ecs_detail::handle species; + ecs_detail::handle entity; + + component_ptrs components; + + template + Component & get() const + { + return *std::get(components); + } + }; }; using handle = ecs_detail::handle; @@ -280,6 +294,9 @@ namespace psemek::util template void apply(Behavior && behavior) const; + template + void apply(Behavior && behavior, handle species) const; + private: std::vector> species_; }; @@ -288,7 +305,7 @@ namespace psemek::util ecs::handle ecs::register_species(std::string name, Components && ... components) { handle result = species_.size(); - species_.push_back(std::make_unique>(std::move(name), std::move(components)...)); + species_.push_back(std::make_unique>(std::move(name), result, std::move(components)...)); return result; } @@ -372,13 +389,14 @@ namespace psemek::util template void ecs::apply(Behavior && behavior) const { - if constexpr (ecs_detail::has_prepare::value) - { - behavior.prepare(); - } - for (auto & s : species_) s->apply(behavior); } + template + void ecs::apply(Behavior && behavior, handle species) const + { + species_[species]->apply(behavior); + } + }