|
- #pragma once
-
- #include <ecs/config.h>
- #include <ecs/tag/system.h>
- #include <ecs/core/system/instance.h>
-
- namespace ecs {
- namespace core {
- namespace system {
- namespace storage {
-
- template<typename T_settings, typename T_entity_handle>
- struct tuple
- {
- public:
- using settings_type = T_settings;
- using entity_handle_type = T_entity_handle;
- using this_type = tuple<settings_type, entity_handle_type>;
-
- private:
- using ssl_type = decltype((settings_type { }).system_signatures());
-
- template<typename T_system_signature>
- using instance_for = system::instance<settings_type, mp::decay_t<T_system_signature>, entity_handle_type>;
-
- template<typename T_system>
- using signature_for = decltype((ssl_type { }).get_by_type(hana::type_c<T_system>));
-
- template<typename T_system>
- using tag_for = tag::system::type<T_system>;
-
- template<typename T_system_tag>
- using tag_to_system = mp::unwrap_t<T_system_tag>;
-
- struct make_instance
- {
- template<typename T_system_signature>
- constexpr decltype(auto) operator()(T_system_signature) const noexcept
- { return instance_for<T_system_signature> { }; }
- };
-
- struct make_tuple
- {
- template<typename... Xs>
- constexpr decltype(auto) operator()(Xs&&... xs) const noexcept
- { return std::make_tuple(std::forward<Xs>(xs)...); }
- };
-
- using storage_type = mp::decay_t<decltype(hana::unpack(
- hana::transform(
- (ssl_type { }).items,
- make_instance { }),
- make_tuple { }))>;
-
- private:
- storage_type _storage;
-
- public:
- constexpr decltype(auto) size() const noexcept
- { return (ssl_type { }).size(); }
-
- template<typename T_func>
- constexpr void for_each(T_func&& f) noexcept
- { hana::for_each(_storage, std::forward<T_func>(f)); }
-
- template<typename T_system>
- inline auto& instance_by_type() noexcept
- { return std::get<instance_for<signature_for<T_system>>>(_storage); }
-
- template<typename T_system>
- inline const auto& instance_by_type() const noexcept
- { return std::get<instance_for<signature_for<T_system>>>(_storage); }
-
- template<typename T_system_index>
- inline auto& instance_by_index(T_system_index) noexcept
- { return std::get<T_system_index { }>(_storage); }
-
- template<typename T_system_index>
- inline const auto& instance_by_index(T_system_index) const noexcept
- { return std::get<T_system_index { }>(_storage); }
-
- template<typename T_system_tag>
- inline auto& instance_by_tag(T_system_tag) noexcept
- { return instance_by_type<tag_to_system<T_system_tag>>(); }
-
- template<typename T_system_tag>
- inline const auto& instance_by_tag(T_system_tag) const noexcept
- { return instance_by_type<tag_to_system<T_system_tag>>(); }
-
- template<typename T_system_signature>
- inline auto& instance_by_signature(T_system_signature ssig) noexcept
- { return instance_by_tag(ssig.tag()); }
-
- template<typename T_system_signature>
- inline const auto& instance_by_signature(T_system_signature ssig) const noexcept
- { return instance_by_tag(ssig.tag()); }
- };
-
- } } } }
|