Introduce util::ecs::behavior::context
This commit is contained in:
parent
bc7378456b
commit
02b29af95a
1 changed files with 43 additions and 25 deletions
|
|
@ -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 <typename Behavior, typename ... Components, std::size_t ... Is>
|
||||
void apply_impl(Behavior & behavior, std::tuple<Components...> *, std::index_sequence<Is...>)
|
||||
{
|
||||
|
|
@ -80,15 +88,16 @@ namespace psemek::util
|
|||
if (!std::apply(all_nonzero, cptrs))
|
||||
return;
|
||||
|
||||
std::tuple<Components *...> cs;
|
||||
typename Behavior::context ctx;
|
||||
ctx.species = id_;
|
||||
|
||||
((std::get<Components *>(cs) = get_species_component<Components>()), ...);
|
||||
((std::get<Components *>(ctx.components) = get_species_component<Components>()), ...);
|
||||
|
||||
auto visit = [&](auto * ... ptrs)
|
||||
{
|
||||
if constexpr (std::is_invocable_v<Behavior, typename Components::data & ..., std::tuple<Components *...> const &>)
|
||||
if constexpr (std::is_invocable_v<Behavior, typename Components::data & ..., typename Behavior::context &>)
|
||||
{
|
||||
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<Components...> species_components_;
|
||||
std::tuple<std::vector<typename Components::data>...> entity_components_;
|
||||
std::vector<handle> list_;
|
||||
|
|
@ -220,12 +226,6 @@ namespace psemek::util
|
|||
}
|
||||
};
|
||||
|
||||
template <typename Behavior>
|
||||
using prepare_helper = decltype(std::declval<Behavior>().prepare());
|
||||
|
||||
template <typename Behavior>
|
||||
using has_prepare = std::experimental::is_detected<prepare_helper, Behavior>;
|
||||
|
||||
}
|
||||
|
||||
struct ecs
|
||||
|
|
@ -235,6 +235,20 @@ namespace psemek::util
|
|||
{
|
||||
using component_types = std::tuple<Components...>;
|
||||
using component_ptrs = std::tuple<Components *...>;
|
||||
|
||||
struct context
|
||||
{
|
||||
ecs_detail::handle species;
|
||||
ecs_detail::handle entity;
|
||||
|
||||
component_ptrs components;
|
||||
|
||||
template <typename Component>
|
||||
Component & get() const
|
||||
{
|
||||
return *std::get<Component *>(components);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
using handle = ecs_detail::handle;
|
||||
|
|
@ -280,6 +294,9 @@ namespace psemek::util
|
|||
template <typename Behavior>
|
||||
void apply(Behavior && behavior) const;
|
||||
|
||||
template <typename Behavior>
|
||||
void apply(Behavior && behavior, handle species) const;
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<ecs_detail::species_base>> 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<ecs_detail::species_impl<Components...>>(std::move(name), std::move(components)...));
|
||||
species_.push_back(std::make_unique<ecs_detail::species_impl<Components...>>(std::move(name), result, std::move(components)...));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -372,13 +389,14 @@ namespace psemek::util
|
|||
template <typename Behavior>
|
||||
void ecs::apply(Behavior && behavior) const
|
||||
{
|
||||
if constexpr (ecs_detail::has_prepare<Behavior>::value)
|
||||
{
|
||||
behavior.prepare();
|
||||
}
|
||||
|
||||
for (auto & s : species_)
|
||||
s->apply(behavior);
|
||||
}
|
||||
|
||||
template <typename Behavior>
|
||||
void ecs::apply(Behavior && behavior, handle species) const
|
||||
{
|
||||
species_[species]->apply(behavior);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue