|
- #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"
-
- namespace ecs {
- namespace signature {
- namespace 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 detail
- {
-
- /**
- * defines a system signature
- *
- * @tparam T_system_tag system tag the signature is defined for
- * @tparam T_options option map for the system signature
- */
- 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:
- /**
- * change the value of an option key
- *
- * @tparam T_key key type to change value for
- * @tparam T_value value type of the new value
- *
- * @param key key to change the value for
- * @param value new value
- *
- * @return updated system signature
- */
- template<typename T_key, typename T_value>
- constexpr decltype(auto) change(const T_key& key, T_value&& value) const noexcept;
-
- /**
- * get the value of an option key
- *
- * @tparam T_key key type to get value for
- *
- * @param key key to get the value for
- *
- * @return value stored for key
- */
- template<typename T_key>
- constexpr decltype(auto) get(const T_key& key) const noexcept;
-
- public: /* misc */
-
- /**
- * get the system tag of this system signature
- *
- * @return system tag of this system signature
- */
- constexpr decltype(auto) tag() const noexcept;
-
- /**
- * check if the given component tag can be written by this system
- *
- * @tparam T_component_tag component tag type to check write access for
- *
- * @param ct component tag to check write access for
- *
- * @retval integral constant TRUE if the given component tag can be written
- * @retval integral constant FALSE if the given component tag can not be written
- */
- template<typename T_component_tag>
- constexpr decltype(auto) can_write(T_component_tag ct) const noexcept;
-
- /**
- * check if the given component tag can be read by this system
- *
- * @tparam T_component_tag component tag type to check read access for
- *
- * @param ct component tag to check read access for
- *
- * @retval integral constant TRUE if the given component tag can be read
- * @retval integral constant FALSE if the given component tag can not be read
- */
- template<typename T_component_tag>
- constexpr decltype(auto) can_read(T_component_tag ct) const noexcept;
-
- public: /* getter */
-
- /**
- * get the value of the parallelism option
- */
- constexpr decltype(auto) parallelism() const noexcept;
-
- /** get a list of system tags that system depends on */
- constexpr decltype(auto) dependencies() const noexcept;
-
- /** get a list of component tags this system wants to read */
- constexpr decltype(auto) read() const noexcept;
-
- /** get a list of component tags this system wants to write */
- constexpr decltype(auto) write() const noexcept;
-
- /** get the output type of the system */
- constexpr decltype(auto) output() const noexcept;
-
- public: /* setter */
-
- /** set the parallelism options
- * @param parallelism is a predicate that takes no parameters and returns a
- * system executor interface */
- template<typename T_parallelism>
- constexpr decltype(auto) parallelism(T_parallelism parallelism) const noexcept;
-
- /** set a list of system tags, that system depends on */
- template<typename... T_system_tags>
- constexpr decltype(auto) dependencies(T_system_tags... tags) const noexcept;
-
- /** set a list of component tags, this system wants to read */
- template<typename... T_component_tags>
- constexpr decltype(auto) read(T_component_tags... tags) const noexcept;
-
- /** set a list of component tags, this system wants to write */
- template<typename... T_component_tags>
- constexpr decltype(auto) write(T_component_tags... tags) const noexcept;
-
- /** set the output type of this system */
- template<typename T_output>
- constexpr decltype(auto) output(T_output output) const noexcept;
- };
-
- /** predicate class to create a system signature */
- struct make_t
- {
- template<typename T_system_tag>
- constexpr decltype(auto) operator()(T_system_tag) const noexcept;
- };
- }
-
- /** predicate to create a system signature */
- constexpr decltype(auto) make = detail::make_t { };
-
- /** predicate to check if a system signature is valid */
- constexpr decltype(auto) is_valid = core::mp::is_valid<detail::signature_t>;
-
- /** predicate to check if a list of system signatures is valid */
- constexpr decltype(auto) is_list = core::mp::is_list<detail::signature_t>;
-
- /** get the system tag type of a system signature type */
- template<typename T_system_sig>
- using tag_type_t = typename core::mp::unwrap_t<T_system_sig>::tag_type;
-
- } } }
|