|
- #pragma once
-
- #include <ecs/config.h>
- #include <ecs/core/mp/core.h>
- #include <ecs/core/mp/list.h>
- #include <ecs/core/mp/option_map.h>
- #include <ecs/tag/system.h>
- #include "./output.h"
- #include "./parallelism.h"
-
- beg_namespace_ecs_signature_system
- {
-
- namespace keys
- {
- constexpr decltype(auto) parallelism = hana::size_c<0>;
- constexpr decltype(auto) dependencies = hana::size_c<1>;
- constexpr decltype(auto) read_components = hana::size_c<2>;
- constexpr decltype(auto) write_components = hana::size_c<3>;
- constexpr decltype(auto) output = hana::size_c<4>;
- }
-
- namespace __impl
- {
- template<typename T_system_tag, typename T_options>
- struct signature_t
- {
- static_assert(tag::system::is_valid(T_system_tag { }) == hana::true_c, "system signature needs a system tags");
-
- using tag_type = T_system_tag;
-
- private:
- template<typename T_key, typename T_value>
- constexpr decltype(auto) change(const T_key& key, T_value&& value) const noexcept
- {
- auto new_options = T_options { }.set(key, std::forward<T_value>(value));
- using impl_type = signature_t<T_system_tag, core::mp::decay_t<decltype(new_options)>>;
- return impl_type { };
- }
-
- template<typename T_key>
- constexpr decltype(auto) get(const T_key& key) const noexcept
- { return T_options { }.at(key); }
-
- public: /* misc */
- constexpr decltype(auto) tag() const noexcept
- { return T_system_tag { }; }
-
- public: /* getter */
- constexpr decltype(auto) parallelism() const noexcept
- { return get(keys::parallelism); }
-
- constexpr decltype(auto) dependencies() const noexcept
- { return get(keys::dependencies); }
-
- constexpr decltype(auto) read() const noexcept
- { return get(keys::read_components); }
-
- constexpr decltype(auto) write() const noexcept
- { return get(keys::write_components); }
-
- constexpr decltype(auto) output() const noexcept
- { return get(keys::output); }
-
- public: /* setter */
- template<typename T_parallelism>
- constexpr decltype(auto) parallelism(T_parallelism parallelism) const noexcept
- { return change(keys::parallelism, parallelism); }
-
- template<typename... T_system_tags>
- constexpr decltype(auto) dependencies(T_system_tags... tags) const noexcept
- { return change(keys::dependencies, core::mp::list::make(tags...)); }
-
- template<typename... T_component_tags>
- constexpr decltype(auto) read(T_component_tags... tags) const noexcept
- { return change(keys::read_components, core::mp::list::make(tags...)); }
-
- template<typename... T_component_tags>
- constexpr decltype(auto) write(T_component_tags... tags) const noexcept
- { return change(keys::write_components, core::mp::list::make(tags...)); }
-
- template<typename T_output>
- constexpr decltype(auto) output(T_output output) const noexcept
- { return change(keys::output, output); }
- };
-
- struct make_t
- {
- template<typename T_system_tag>
- constexpr decltype(auto) operator()(T_system_tag) const noexcept
- {
- using namespace ::ecs::core::mp;
-
- auto options = option_map::make()
- .add(keys::parallelism, parallelism::none())
- .add(keys::dependencies, list::empty)
- .add(keys::read_components, list::empty)
- .add(keys::write_components, list::empty)
- .add(keys::output, output::none);
-
- using signature_type = signature_t<T_system_tag, decay_t<decltype(options)>>;
-
- return signature_type { };
- }
- };
- }
-
- constexpr decltype(auto) make = __impl::make_t { };
-
- constexpr decltype(auto) is_valid = core::mp::is_valid<__impl::signature_t>;
-
- constexpr decltype(auto) is_list = core::mp::is_list<__impl::signature_t>;
-
- template<typename T_system_sig>
- using tag_type = typename core::mp::unwrap_t<T_system_sig>::tag_type;
-
- }
- end_namespace_ecs_signature_system
|