11#include " core.hh"
22
3- #include < concepts>
4- #include < fenv.h>
53#include < ranges>
6- #include < set>
74#include < string>
85#include < type_traits>
96#include < unordered_map>
1714#include " rt_entt_codegen/shared/ecsact_entt_details.hh"
1815#include " rt_entt_codegen/shared/util.hh"
1916#include " rt_entt_codegen/shared/comps_with_caps.hh"
17+ #include " rt_entt_codegen/shared/sorting.hh"
2018
2119using capability_t =
2220 std::unordered_map<ecsact_component_like_id, ecsact_system_capability>;
@@ -26,6 +24,7 @@ concept system_or_action =
2624 std::same_as<T, ecsact_system_id> || std::same_as<T, ecsact_action_id>;
2725
2826using ecsact::rt_entt_codegen::system_comps_with_caps;
27+ using ecsact::rt_entt_codegen::system_needs_sorted_entities;
2928
3029template <system_or_action T>
3130static auto print_sys_exec_ctx_action (
@@ -483,58 +482,6 @@ static auto print_sys_exec_ctx_other(
483482 ctx.write (" return nullptr;" );
484483}
485484
486- static auto comma_delim (auto && range) -> std::string {
487- auto result = std::string{};
488-
489- for (auto str : range) {
490- result += str + " , " ;
491- }
492-
493- if (result.ends_with (" , " )) {
494- result = result.substr (0 , result.size () - 2 );
495- }
496-
497- return result;
498- }
499-
500- static auto make_view ( //
501- ecsact::codegen_plugin_context& ctx,
502- auto && view_var_name,
503- auto && registry_var_name,
504- const ecsact::rt_entt_codegen::ecsact_entt_system_details& details,
505- std::vector<std::string> additional_components = {}
506- ) -> void {
507- using namespace std ::string_literals;
508- using ecsact::rt_entt_codegen::util::decl_cpp_ident;
509- using std::views::transform;
510-
511- ctx.write (" auto " , view_var_name, " = " , registry_var_name, " .view<" );
512-
513- ctx.write (comma_delim (
514- details.get_comps | transform (decl_cpp_ident<ecsact_component_like_id>)
515- ));
516-
517- if (!additional_components.empty ()) {
518- ctx.write (" , " );
519- ctx.write (comma_delim (additional_components));
520- }
521-
522- ctx.write (" >(" );
523-
524- if (!details.exclude_comps .empty ()) {
525- ctx.write (
526- " ::entt::exclude<" ,
527- comma_delim (
528- details.exclude_comps |
529- transform (decl_cpp_ident<ecsact_component_like_id>)
530- ),
531- " >"
532- );
533- }
534-
535- ctx.write (" );\n " );
536- }
537-
538485template <typename SystemLikeID>
539486static auto print_apply_pendings (
540487 ecsact::codegen_plugin_context& ctx,
@@ -634,6 +581,11 @@ static auto print_ecsact_entt_system_details(
634581 options.system_name
635582 );
636583
584+ auto system_sorting_struct_name = std::format (
585+ " ::ecsact::entt::detail::system_sorted<{}>" ,
586+ options.system_name
587+ );
588+
637589 auto additional_view_components = std::vector<std::string>{};
638590
639591 if (lazy_iteration_rate > 0 ) {
@@ -647,13 +599,22 @@ static auto print_ecsact_entt_system_details(
647599 additional_view_components.push_back (pending_lazy_exec_struct);
648600 }
649601
650- make_view (
602+ if (system_needs_sorted_entities (options.sys_like_id , details)) {
603+ additional_view_components.push_back (system_sorting_struct_name);
604+ }
605+
606+ ecsact::rt_entt_codegen::util::make_view (
651607 ctx,
652608 " view" ,
653609 options.registry_var_name ,
654610 details,
655611 additional_view_components
656612 );
613+
614+ if (system_needs_sorted_entities (options.sys_like_id , details)) {
615+ ctx.write (" view.use<" , system_sorting_struct_name, " >();\n " );
616+ }
617+
657618 block (ctx, " struct : ecsact_system_execution_context " , [&] {
658619 ctx.write (" decltype(view)* view;\n " );
659620
@@ -814,7 +775,21 @@ static auto print_ecsact_entt_system_details(
814775 );
815776 ctx.write (" assert(iteration_count_ <= lazy_iteration_rate_);\n " );
816777 block (ctx, " if(iteration_count_ < lazy_iteration_rate_)" , [&] {
817- make_view (
778+ ctx.write (
779+ " _recalc_sorting_hash<" ,
780+ options.system_name ,
781+ " >(" ,
782+ options.registry_var_name ,
783+ " );\n "
784+ );
785+ ctx.write (
786+ options.registry_var_name ,
787+ " .sort<" ,
788+ system_sorting_struct_name,
789+ " >([](const auto& a, const auto& b) { return a.hash < b.hash; });\n "
790+ );
791+
792+ ecsact::rt_entt_codegen::util::make_view (
818793 ctx,
819794 " view_no_pending_lazy_" ,
820795 options.registry_var_name ,
@@ -914,7 +889,12 @@ static auto print_other_contexts(
914889 auto other_details =
915890 ecsact_entt_system_details::from_capabilities (assoc_detail.capabilities );
916891
917- make_view (ctx, view_name, " registry" , other_details);
892+ ecsact::rt_entt_codegen::util::make_view (
893+ ctx,
894+ view_name,
895+ " registry" ,
896+ other_details
897+ );
918898
919899 block (ctx, " struct " + struct_header, [&] {
920900 using namespace std ::string_literals;
@@ -1011,7 +991,7 @@ static auto print_trivial_system_like(
1011991 .parameter (" ecsact_system_execution_context*" , " parent_context" )
1012992 .return_type (" void" );
1013993
1014- make_view (ctx, " view" , " registry" , details);
994+ ecsact::rt_entt_codegen::util:: make_view (ctx, " view" , " registry" , details);
1015995
1016996 block (ctx, " for(auto entity : view)" , [&] {
1017997 for (auto && [comp_id, capability] : sys_capabilities) {
0 commit comments