Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

118 linhas
4.4 KiB

  1. #pragma once
  2. #include <ecs/config.h>
  3. #include <ecs/core/mp/core.h>
  4. #include <ecs/core/mp/list.h>
  5. #include <ecs/core/mp/option_map.h>
  6. #include <ecs/tag/system.h>
  7. #include "./output.h"
  8. #include "./parallelism.h"
  9. beg_namespace_ecs_signature_system
  10. {
  11. namespace keys
  12. {
  13. constexpr decltype(auto) parallelism = hana::size_c<0>;
  14. constexpr decltype(auto) dependencies = hana::size_c<1>;
  15. constexpr decltype(auto) read_components = hana::size_c<2>;
  16. constexpr decltype(auto) write_components = hana::size_c<3>;
  17. constexpr decltype(auto) output = hana::size_c<4>;
  18. }
  19. namespace __impl
  20. {
  21. template<typename T_system_tag, typename T_options>
  22. struct signature_t
  23. {
  24. static_assert(tag::system::is_valid(T_system_tag { }) == hana::true_c, "system signature needs a system tags");
  25. using tag_type = T_system_tag;
  26. private:
  27. template<typename T_key, typename T_value>
  28. constexpr decltype(auto) change(const T_key& key, T_value&& value) const noexcept
  29. {
  30. auto new_options = T_options { }.set(key, std::forward<T_value>(value));
  31. using impl_type = signature_t<T_system_tag, core::mp::decay_t<decltype(new_options)>>;
  32. return impl_type { };
  33. }
  34. template<typename T_key>
  35. constexpr decltype(auto) get(const T_key& key) const noexcept
  36. { return T_options { }.at(key); }
  37. public: /* misc */
  38. constexpr decltype(auto) tag() const noexcept
  39. { return T_system_tag { }; }
  40. public: /* getter */
  41. constexpr decltype(auto) parallelism() const noexcept
  42. { return get(keys::parallelism); }
  43. constexpr decltype(auto) dependencies() const noexcept
  44. { return get(keys::dependencies); }
  45. constexpr decltype(auto) read() const noexcept
  46. { return get(keys::read_components); }
  47. constexpr decltype(auto) write() const noexcept
  48. { return get(keys::write_components); }
  49. constexpr decltype(auto) output() const noexcept
  50. { return get(keys::output); }
  51. public: /* setter */
  52. template<typename T_parallelism>
  53. constexpr decltype(auto) parallelism(T_parallelism parallelism) const noexcept
  54. { return change(keys::parallelism, parallelism); }
  55. template<typename... T_system_tags>
  56. constexpr decltype(auto) dependencies(T_system_tags... tags) const noexcept
  57. { return change(keys::dependencies, core::mp::list::make(tags...)); }
  58. template<typename... T_component_tags>
  59. constexpr decltype(auto) read(T_component_tags... tags) const noexcept
  60. { return change(keys::read_components, core::mp::list::make(tags...)); }
  61. template<typename... T_component_tags>
  62. constexpr decltype(auto) write(T_component_tags... tags) const noexcept
  63. { return change(keys::write_components, core::mp::list::make(tags...)); }
  64. template<typename T_output>
  65. constexpr decltype(auto) output(T_output output) const noexcept
  66. { return change(keys::output, output); }
  67. };
  68. struct make_t
  69. {
  70. template<typename T_system_tag>
  71. constexpr decltype(auto) operator()(T_system_tag) const noexcept
  72. {
  73. using namespace ::ecs::core::mp;
  74. auto options = option_map::make()
  75. .add(keys::parallelism, parallelism::none())
  76. .add(keys::dependencies, list::empty)
  77. .add(keys::read_components, list::empty)
  78. .add(keys::write_components, list::empty)
  79. .add(keys::output, output::none);
  80. using signature_type = signature_t<T_system_tag, decay_t<decltype(options)>>;
  81. return signature_type { };
  82. }
  83. };
  84. }
  85. constexpr decltype(auto) make = __impl::make_t { };
  86. constexpr decltype(auto) is_valid = core::mp::is_valid<__impl::signature_t>;
  87. constexpr decltype(auto) is_list = core::mp::is_list<__impl::signature_t>;
  88. template<typename T_system_sig>
  89. using tag_type = typename core::mp::unwrap_t<T_system_sig>::tag_type;
  90. }
  91. end_namespace_ecs_signature_system