You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 line
3.7 KiB

  1. #pragma once
  2. #include <ecs/config.h>
  3. #include <ecs/tag/system.h>
  4. #include <ecs/signature/system.h>
  5. beg_namespace_ecs_signature_list_system
  6. {
  7. namespace __impl
  8. {
  9. template<typename... T_system_signatures>
  10. struct signature_list_t
  11. {
  12. public:
  13. core::mp::list::type<T_system_signatures...> items;
  14. public: /* misc */
  15. constexpr decltype(auto) size() const noexcept
  16. { return hana::size(items); }
  17. public: /* get */
  18. constexpr decltype(auto) tags() const noexcept
  19. {
  20. return hana::unpack(
  21. hana::transform(items, [](auto& ssig){
  22. return core::mp::unwrap(ssig).tag();
  23. }),
  24. core::mp::list::make);
  25. }
  26. template<typename T_system_tag>
  27. constexpr decltype(auto) get_by_tag(T_system_tag st) const noexcept
  28. {
  29. static_assert(decltype(tag::system::is_valid(st)) { });
  30. using namespace ::ecs::core::mp;
  31. return *hana::find_if(items, [](auto ssig){
  32. using is_same_type = std::is_same<
  33. decay_t<decltype(unwrapped(ssig).tag())>,
  34. decay_t<decltype(st)>>;
  35. return is_same_type { };
  36. });
  37. }
  38. template<typename T_system>
  39. constexpr decltype(auto) get_by_type(T_system) const noexcept
  40. {
  41. using system_type = typename core::mp::decay_t<T_system>::type;
  42. return get_by_tag(tag::system::value<system_type>);
  43. }
  44. template<typename T_system>
  45. constexpr decltype(auto) get_by_type() const noexcept
  46. { return get_by_tag(tag::system::value<T_system>); }
  47. template<typename T_index>
  48. constexpr decltype(auto) get_by_index(T_index index) const noexcept
  49. { return hana::at(items, index); }
  50. public: /* id */
  51. template<typename T_system_signature>
  52. constexpr decltype(auto) id_by_signature(T_system_signature ssig) const noexcept
  53. { return core::mp::list::index_of(items, ssig); }
  54. template<typename T_system>
  55. constexpr decltype(auto) id_by_type() const noexcept
  56. { return id_by_signature(get_by_type<T_system>()); }
  57. template<typename T_system_tag>
  58. constexpr decltype(auto) id_by_tag(T_system_tag st) const noexcept
  59. { return id_by_signature(signature_by_tag(st)); }
  60. };
  61. struct make_t
  62. {
  63. template<typename... T_system_signatures>
  64. constexpr decltype(auto) operator()(T_system_signatures... sss) const noexcept
  65. {
  66. using namespace ::ecs::core::mp;
  67. static_assert(
  68. decltype(signature::system::is_valid(sss...)) { },
  69. "system::signature_list::make() needs a list of system signatures");
  70. return signature_list_t<hana::type<core::mp::decay_t<T_system_signatures>>...> { };
  71. }
  72. };
  73. struct is_valid_t
  74. {
  75. template<typename T_system_signature_list>
  76. constexpr decltype(auto) operator()(T_system_signature_list&& ssl) const noexcept
  77. {
  78. return hana::all_of(
  79. hana::transform(
  80. std::forward<T_system_signature_list>(ssl).items, core::mp::unwrap),
  81. signature::system::is_valid);
  82. }
  83. };
  84. }
  85. constexpr decltype(auto) make = __impl::make_t { };
  86. constexpr decltype(auto) is_valid = __impl::is_valid_t { };
  87. }
  88. end_namespace_ecs_signature_list_system