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
|
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_species_component(std::type_index component_type) = 0;
|
||||||
virtual void * get_entity_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:
|
private:
|
||||||
|
|
||||||
|
std::string name_;
|
||||||
|
handle id_;
|
||||||
|
|
||||||
template <typename Behavior, typename ... Components, std::size_t ... Is>
|
template <typename Behavior, typename ... Components, std::size_t ... Is>
|
||||||
void apply_impl(Behavior & behavior, std::tuple<Components...> *, std::index_sequence<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))
|
if (!std::apply(all_nonzero, cptrs))
|
||||||
return;
|
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)
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -108,7 +117,10 @@ namespace psemek::util
|
||||||
for (std::size_t i = 0; i < count; ++i)
|
for (std::size_t i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
if (*list == i)
|
if (*list == i)
|
||||||
|
{
|
||||||
|
ctx.entity = i;
|
||||||
std::apply(visit, cptrs);
|
std::apply(visit, cptrs);
|
||||||
|
}
|
||||||
std::apply(increment, cptrs);
|
std::apply(increment, cptrs);
|
||||||
++list;
|
++list;
|
||||||
}
|
}
|
||||||
|
|
@ -119,16 +131,11 @@ namespace psemek::util
|
||||||
struct species_impl
|
struct species_impl
|
||||||
: species_base
|
: species_base
|
||||||
{
|
{
|
||||||
species_impl(std::string name, Components && ... components)
|
species_impl(std::string name, handle id, Components && ... components)
|
||||||
: name_(std::move(name))
|
: species_base(std::move(name), id)
|
||||||
, species_components_{std::move(components)...}
|
, species_components_{std::move(components)...}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::string_view name() const override
|
|
||||||
{
|
|
||||||
return name_;
|
|
||||||
}
|
|
||||||
|
|
||||||
using species_base::get_species_component;
|
using species_base::get_species_component;
|
||||||
using species_base::get_entity_component;
|
using species_base::get_entity_component;
|
||||||
|
|
||||||
|
|
@ -170,7 +177,6 @@ namespace psemek::util
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string name_;
|
|
||||||
std::tuple<Components...> species_components_;
|
std::tuple<Components...> species_components_;
|
||||||
std::tuple<std::vector<typename Components::data>...> entity_components_;
|
std::tuple<std::vector<typename Components::data>...> entity_components_;
|
||||||
std::vector<handle> list_;
|
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
|
struct ecs
|
||||||
|
|
@ -235,6 +235,20 @@ namespace psemek::util
|
||||||
{
|
{
|
||||||
using component_types = std::tuple<Components...>;
|
using component_types = std::tuple<Components...>;
|
||||||
using component_ptrs = 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;
|
using handle = ecs_detail::handle;
|
||||||
|
|
@ -280,6 +294,9 @@ namespace psemek::util
|
||||||
template <typename Behavior>
|
template <typename Behavior>
|
||||||
void apply(Behavior && behavior) const;
|
void apply(Behavior && behavior) const;
|
||||||
|
|
||||||
|
template <typename Behavior>
|
||||||
|
void apply(Behavior && behavior, handle species) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::unique_ptr<ecs_detail::species_base>> species_;
|
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)
|
ecs::handle ecs::register_species(std::string name, Components && ... components)
|
||||||
{
|
{
|
||||||
handle result = species_.size();
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -372,13 +389,14 @@ namespace psemek::util
|
||||||
template <typename Behavior>
|
template <typename Behavior>
|
||||||
void ecs::apply(Behavior && behavior) const
|
void ecs::apply(Behavior && behavior) const
|
||||||
{
|
{
|
||||||
if constexpr (ecs_detail::has_prepare<Behavior>::value)
|
|
||||||
{
|
|
||||||
behavior.prepare();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto & s : species_)
|
for (auto & s : species_)
|
||||||
s->apply(behavior);
|
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