選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

99 行
3.4 KiB

  1. #pragma once
  2. #include <ecs/config.h>
  3. #include <ecs/tag/system.h>
  4. #include <ecs/core/system/instance.h>
  5. namespace ecs {
  6. namespace core {
  7. namespace system {
  8. namespace storage {
  9. template<typename T_settings, typename T_entity_handle>
  10. struct tuple
  11. {
  12. public:
  13. using settings_type = T_settings;
  14. using entity_handle_type = T_entity_handle;
  15. using this_type = tuple<settings_type, entity_handle_type>;
  16. private:
  17. using ssl_type = decltype((settings_type { }).system_signatures());
  18. template<typename T_system_signature>
  19. using instance_for = system::instance<settings_type, mp::decay_t<T_system_signature>, entity_handle_type>;
  20. template<typename T_system>
  21. using signature_for = decltype((ssl_type { }).get_by_type(hana::type_c<T_system>));
  22. template<typename T_system>
  23. using tag_for = tag::system::type<T_system>;
  24. template<typename T_system_tag>
  25. using tag_to_system = mp::unwrap_t<T_system_tag>;
  26. struct make_instance
  27. {
  28. template<typename T_system_signature>
  29. constexpr decltype(auto) operator()(T_system_signature) const noexcept
  30. { return instance_for<T_system_signature> { }; }
  31. };
  32. struct make_tuple
  33. {
  34. template<typename... Xs>
  35. constexpr decltype(auto) operator()(Xs&&... xs) const noexcept
  36. { return std::make_tuple(std::forward<Xs>(xs)...); }
  37. };
  38. using storage_type = mp::decay_t<decltype(hana::unpack(
  39. hana::transform(
  40. (ssl_type { }).items,
  41. make_instance { }),
  42. make_tuple { }))>;
  43. private:
  44. storage_type _storage;
  45. public:
  46. constexpr decltype(auto) size() const noexcept
  47. { return (ssl_type { }).size(); }
  48. template<typename T_func>
  49. constexpr void for_each(T_func&& f) noexcept
  50. { hana::for_each(_storage, std::forward<T_func>(f)); }
  51. template<typename T_system>
  52. inline auto& instance_by_type() noexcept
  53. { return std::get<instance_for<signature_for<T_system>>>(_storage); }
  54. template<typename T_system>
  55. inline const auto& instance_by_type() const noexcept
  56. { return std::get<instance_for<signature_for<T_system>>>(_storage); }
  57. template<typename T_system_index>
  58. inline auto& instance_by_index(T_system_index) noexcept
  59. { return std::get<T_system_index { }>(_storage); }
  60. template<typename T_system_index>
  61. inline const auto& instance_by_index(T_system_index) const noexcept
  62. { return std::get<T_system_index { }>(_storage); }
  63. template<typename T_system_tag>
  64. inline auto& instance_by_tag(T_system_tag) noexcept
  65. { return instance_by_type<tag_to_system<T_system_tag>>(); }
  66. template<typename T_system_tag>
  67. inline const auto& instance_by_tag(T_system_tag) const noexcept
  68. { return instance_by_type<tag_to_system<T_system_tag>>(); }
  69. template<typename T_system_signature>
  70. inline auto& instance_by_signature(T_system_signature ssig) noexcept
  71. { return instance_by_tag(ssig.tag()); }
  72. template<typename T_system_signature>
  73. inline const auto& instance_by_signature(T_system_signature ssig) const noexcept
  74. { return instance_by_tag(ssig.tag()); }
  75. };
  76. } } } }