diff --git a/build_recipe.yml b/build_recipe.yml index fc1e578..be98340 100644 --- a/build_recipe.yml +++ b/build_recipe.yml @@ -179,6 +179,8 @@ sources: outdir: include/ecsact/entt/detail - path: ./ecsact/entt/detail/globals.hh outdir: include/ecsact/entt/detail + - path: ./ecsact/entt/detail/registry.hh + outdir: include/ecsact/entt/detail - path: ./ecsact/entt/detail/internal_markers.hh outdir: include/ecsact/entt/detail - path: ./ecsact/entt/detail/system_execution_context.hh diff --git a/ecsact/entt/detail/apply_pending.hh b/ecsact/entt/detail/apply_pending.hh index 34e3323..80162ab 100644 --- a/ecsact/entt/detail/apply_pending.hh +++ b/ecsact/entt/detail/apply_pending.hh @@ -7,7 +7,7 @@ namespace ecsact::entt::detail { template -auto apply_pending_add(::entt::registry& registry) -> void { +auto apply_pending_add(ecsact::entt::registry_t& registry) -> void { if constexpr(std::is_empty_v) { registry.view>().each([&](auto entity) { registry.emplace(entity); @@ -26,7 +26,7 @@ auto apply_pending_add(::entt::registry& registry) -> void { } template -auto apply_pending_remove(::entt::registry& registry) -> void { +auto apply_pending_remove(ecsact::entt::registry_t& registry) -> void { registry.view>().each([&](auto entity) { if constexpr(!std::is_empty_v) { registry.erase>(entity); diff --git a/ecsact/entt/detail/globals.hh b/ecsact/entt/detail/globals.hh index 1268fed..791da4c 100644 --- a/ecsact/entt/detail/globals.hh +++ b/ecsact/entt/detail/globals.hh @@ -7,6 +7,7 @@ #include "ecsact/runtime/core.h" #include "ecsact/runtime/dynamic.h" #include "ecsact/entt/detail/system_execution_context.hh" +#include "ecsact/entt/detail/registry.hh" /** * A small set of globals expected to be available the ecsact_rt_entt_codegen @@ -19,7 +20,7 @@ namespace ecsact::entt::detail::globals { */ extern std::unordered_map< // ecsact_registry_id, - ::entt::registry> + ecsact::entt::registry_t> registries; /** diff --git a/ecsact/entt/detail/internal_markers.hh b/ecsact/entt/detail/internal_markers.hh index dda2f80..453918c 100644 --- a/ecsact/entt/detail/internal_markers.hh +++ b/ecsact/entt/detail/internal_markers.hh @@ -87,7 +87,7 @@ constexpr bool system_markers_unimplemented_by_codegen = false; template auto add_system_markers_if_needed( // - ::entt::registry&, + ecsact::entt::registry_t&, ecsact::entt::entity_id ) -> void { static_assert(system_markers_unimplemented_by_codegen, R"( @@ -101,7 +101,7 @@ auto add_system_markers_if_needed( // template auto remove_system_markers_if_needed( // - ::entt::registry&, + ecsact::entt::registry_t&, ecsact::entt::entity_id ) -> void { static_assert(system_markers_unimplemented_by_codegen, R"( @@ -115,7 +115,7 @@ auto remove_system_markers_if_needed( // template auto add_exec_itr_beforechange_if_needed( // - ::entt::registry&, + ecsact::entt::registry_t&, ecsact::entt::entity_id ) -> void { static_assert(system_markers_unimplemented_by_codegen, R"( diff --git a/ecsact/entt/detail/registry.hh b/ecsact/entt/detail/registry.hh new file mode 100644 index 0000000..0136693 --- /dev/null +++ b/ecsact/entt/detail/registry.hh @@ -0,0 +1,8 @@ +#pragma once + +#include "entt/entity/registry.hpp" + +namespace ecsact::entt { + +using registry_t = ::entt::basic_registry<::entt::entity>; +} diff --git a/ecsact/entt/detail/system_execution_context.hh b/ecsact/entt/detail/system_execution_context.hh index c921f54..16272fb 100644 --- a/ecsact/entt/detail/system_execution_context.hh +++ b/ecsact/entt/detail/system_execution_context.hh @@ -10,6 +10,7 @@ #include "ecsact/runtime/common.h" #include "ecsact/entt/event_markers.hh" #include "ecsact/entt/entity.hh" +#include "ecsact/entt/detail/registry.hh" namespace ecsact::entt { /** @@ -30,10 +31,10 @@ constexpr auto underlying_assoc_index(assoc_index n) -> unsigned { } // namespace ecsact::entt struct ecsact_system_execution_context { - ecsact_system_like_id id; - ecsact::entt::entity_id entity; - ::entt::registry* registry = nullptr; - const void* action_data = nullptr; + ecsact_system_like_id id; + ecsact::entt::entity_id entity; + ecsact::entt::registry_t* registry = nullptr; + const void* action_data = nullptr; // pass in the context to this class that's a pointer // context(ptr) = parent_ctx(ptr) diff --git a/ecsact/entt/error_check.hh b/ecsact/entt/error_check.hh index c14462a..fff545d 100644 --- a/ecsact/entt/error_check.hh +++ b/ecsact/entt/error_check.hh @@ -19,7 +19,7 @@ namespace ecsact::entt { template auto check_add_component_error( // - ::entt::registry&, + ecsact::entt::registry_t&, ::ecsact::entt::entity_id, const C& ) -> ecsact_add_error { @@ -34,7 +34,7 @@ auto check_add_component_error( // template auto check_update_component_error( // - ::entt::registry&, + ecsact::entt::registry_t&, ::ecsact::entt::entity_id, const C& ) -> ecsact_update_error { @@ -49,7 +49,7 @@ auto check_update_component_error( // template auto check_action_error( // - ::entt::registry&, + ecsact::entt::registry_t&, const A& ) -> ecsact_execute_systems_error { static_assert(detail::error_check_unimplemented_by_codegen, R"( diff --git a/ecsact/entt/event_markers.hh b/ecsact/entt/event_markers.hh index 2fa0e58..c7495da 100644 --- a/ecsact/entt/event_markers.hh +++ b/ecsact/entt/event_markers.hh @@ -10,12 +10,6 @@ namespace ecsact::entt { template struct component_added {}; -/** - * Marker to indicate that a component has been changed during execution - */ -template -struct component_updated {}; - /** * Marker to indicate that a component has been removed */ diff --git a/ecsact/entt/execution.hh b/ecsact/entt/execution.hh index 090ebc0..f407d0e 100644 --- a/ecsact/entt/execution.hh +++ b/ecsact/entt/execution.hh @@ -93,7 +93,7 @@ struct actions_map { */ template auto execute_system( // - ::entt::registry& registry, + ecsact::entt::registry_t& registry, ecsact_system_execution_context* parent, const ecsact::entt::actions_map& actions_map ) -> void { @@ -115,7 +115,7 @@ auto execute_system( // */ template auto execute_actions( // - ::entt::registry& registry, + ecsact::entt::registry_t& registry, ecsact_system_execution_context* parent, const ecsact::entt::actions_map& actions_map ) -> void { @@ -129,7 +129,7 @@ auto execute_actions( // } using execute_fn_t = void (*)( - ::entt::registry& registry, + ecsact::entt::registry_t& registry, ecsact_system_execution_context* parent, const ecsact::entt::actions_map& actions_map ); @@ -140,7 +140,7 @@ using execute_fn_t = void (*)( * `ecsact_rt_entt_codegen`. */ template -auto prepare_system_like(::entt::registry&) -> void { +auto prepare_system_like(ecsact::entt::registry_t&) -> void { static_assert(detail::unimplemented_by_codegen, R"( ----------------------------------------------------------------------------- | (!) CODEGEN ERROR | @@ -155,7 +155,8 @@ auto prepare_system_like(::entt::registry&) -> void { * entity. */ template -auto entity_matches_system(::entt::registry&, ecsact::entt::entity_id) -> bool { +auto entity_matches_system(ecsact::entt::registry_t&, ecsact::entt::entity_id) + -> bool { static_assert(detail::unimplemented_by_codegen, R"( ----------------------------------------------------------------------------- | (!) CODEGEN ERROR | diff --git a/ecsact/entt/registry_util.hh b/ecsact/entt/registry_util.hh index 7dea723..bd3d51d 100644 --- a/ecsact/entt/registry_util.hh +++ b/ecsact/entt/registry_util.hh @@ -3,12 +3,13 @@ #include #include "entt/entity/registry.hpp" #include "ecsact/entt/detail/globals.hh" +#include "ecsact/entt/detail/registry.hh" namespace ecsact::entt { inline auto get_registry( // ecsact_registry_id id -) -> ::entt::registry& { +) -> ecsact::entt::registry_t& { using ecsact::entt::detail::globals::registries; // Check to make sure we're not trying to get a registry that doesn't exist @@ -18,7 +19,7 @@ inline auto get_registry( // } inline auto create_registry() - -> std::tuple { + -> std::tuple { using ecsact::entt::detail::globals::last_registry_id; using ecsact::entt::detail::globals::registries; diff --git a/ecsact/entt/wrapper/core.hh b/ecsact/entt/wrapper/core.hh index 4aa57c3..901cd1d 100644 --- a/ecsact/entt/wrapper/core.hh +++ b/ecsact/entt/wrapper/core.hh @@ -118,6 +118,8 @@ inline auto update_component( // [[maybe_unused]] ecsact_component_id component_id, const void* component_data ) -> ecsact_update_error { + using ecsact::entt::detail::exec_beforechange_storage; + auto& reg = ecsact::entt::get_registry(registry_id); auto entity = ecsact::entt::entity_id{entity_id}; assert(C::id == component_id); @@ -129,10 +131,15 @@ inline auto update_component( // *static_cast(component_data) ); - if(err == ECSACT_UPDATE_OK) { - reg.replace(entity, *static_cast(component_data)); + if(err != ECSACT_UPDATE_OK) { + return err; } + const auto& in_component = *static_cast(component_data); + auto& current_component = reg.template get(entity); + + current_component = in_component; + return err; } @@ -143,6 +150,8 @@ inline auto update_component_exec_options( // [[maybe_unused]] ecsact_component_id component_id, const void* component_data ) -> ecsact_update_error { + using ecsact::entt::detail::exec_beforechange_storage; + auto& reg = ecsact::entt::get_registry(registry_id); auto entity = ecsact::entt::entity_id{entity_id}; assert(C::id == component_id); @@ -154,11 +163,20 @@ inline auto update_component_exec_options( // *static_cast(component_data) ); - if(err == ECSACT_UPDATE_OK) { - reg.replace(entity, *static_cast(component_data)); - reg.template emplace_or_replace>(entity); + if(err != ECSACT_UPDATE_OK) { + return err; } + const auto& in_component = *static_cast(component_data); + auto& beforechange = reg.template get>(entity); + auto& current_component = reg.template get(entity); + + if(!beforechange.has_update_occurred) { + beforechange.value = current_component; + beforechange.has_update_occurred = true; + } + current_component = in_component; + return err; } @@ -177,7 +195,6 @@ auto remove_component( reg.remove>(entity); } reg.template remove>(entity); - reg.template remove>(entity); reg.template emplace_or_replace>(entity); ecsact::entt::detail::remove_system_markers_if_needed(reg, entity); } @@ -203,7 +220,6 @@ auto remove_component_exec_options( reg.template erase(entity); reg.template remove>(entity); - reg.template remove>(entity); reg.template emplace_or_replace>(entity); if constexpr(!std::is_empty_v) { @@ -295,30 +311,30 @@ auto _trigger_update_component_event( ecsact_registry_id registry_id, ecsact::entt::detail::execution_events_collector& events_collector ) -> void { - using ecsact::entt::component_updated; + using ecsact::entt::detail::beforeremove_storage; using ecsact::entt::detail::exec_beforechange_storage; + // + if(!events_collector.has_update_callback()) { return; } auto& reg = ecsact::entt::get_registry(registry_id); if constexpr(!C::transient && !std::is_empty_v) { - ::entt::basic_view changed_view{ - reg.template storage(), - reg.template storage>(), - reg.template storage>(), - }; + auto comp_view = reg.view>( // + ::entt::exclude> + ); - for(ecsact::entt::entity_id entity : changed_view) { + for(ecsact::entt::entity_id entity : comp_view) { auto& before = - changed_view.template get>(entity); - auto& current = changed_view.template get(entity); - before.has_update_occurred = false; + comp_view.template get>(entity); + auto& current = comp_view.template get(entity); - if(before.value != current) { + if(before.has_update_occurred && before.value != current) { events_collector.invoke_update_callback(entity, current); } + before.has_update_occurred = false; } } } @@ -384,7 +400,6 @@ inline auto clear_component(ecsact_registry_id registry_id) -> void { auto& reg = ecsact::entt::get_registry(registry_id); reg.clear>(); - reg.clear>(); reg.clear>(); } @@ -404,10 +419,13 @@ inline auto prepare_component(ecsact_registry_id registry_id) -> void { reg.template storage(); reg.template storage>(); reg.template storage>(); + reg.template storage>(); + reg.template storage>(); + reg.template storage>(); if constexpr(!std::is_empty_v) { - reg.storage>(); - reg.template storage>(); + reg.template storage>(); + reg.template storage>(); } } @@ -418,6 +436,7 @@ inline auto prepare_system(ecsact_registry_id registry_id) -> void { reg.template storage>(); reg.template storage>(); + reg.template storage>(); } template @@ -435,8 +454,10 @@ auto has_component_changed(entt::entity_id entity, V& view) -> bool { } template -auto update_exec_itr_beforechange(entt::entity_id entity, ::entt::registry& reg) - -> void { +auto update_exec_itr_beforechange( + entt::entity_id entity, + ecsact::entt::registry_t& reg +) -> void { auto comp = reg.get(entity); auto& beforechange_comp = reg.get>(entity); diff --git a/ecsact/entt/wrapper/dynamic.hh b/ecsact/entt/wrapper/dynamic.hh index 5921938..7007384 100644 --- a/ecsact/entt/wrapper/dynamic.hh +++ b/ecsact/entt/wrapper/dynamic.hh @@ -48,8 +48,8 @@ auto context_add( template auto component_add_trivial( - ::entt::registry& registry, - ecsact::entt::entity_id entity_id + ecsact::entt::registry_t& registry, + ecsact::entt::entity_id entity_id ) -> void { using ecsact::entt::component_added; using ecsact::entt::component_removed; @@ -75,7 +75,6 @@ auto context_remove( assert(ecsact_id_cast(C::id) == component_id); using ecsact::entt::component_removed; - using ecsact::entt::component_updated; using ecsact::entt::detail::beforeremove_storage; using ecsact::entt::detail::pending_remove; @@ -83,7 +82,6 @@ auto context_remove( auto& registry = *context->registry; registry.template remove>(entity); - registry.template remove>(entity); registry.template emplace_or_replace>(entity); registry.template emplace_or_replace>(entity); @@ -100,17 +98,15 @@ auto context_remove( template auto component_remove_trivial( - ::entt::registry& registry, - ecsact::entt::entity_id entity_id, - auto& view + ecsact::entt::registry_t& registry, + ecsact::entt::entity_id entity_id, + auto& view ) -> void { using ecsact::entt::component_removed; - using ecsact::entt::component_updated; using ecsact::entt::detail::beforeremove_storage; using ecsact::entt::detail::pending_remove; registry.template remove>(entity_id); - registry.template remove>(entity_id); registry.template emplace_or_replace>(entity_id); registry.template emplace_or_replace>(entity_id); @@ -131,10 +127,7 @@ auto context_get( void* out_component_data, auto& view ) -> void { - auto entity = context->entity; - const auto& registry = *context->registry; - - assert(registry.template any_of(entity)); + auto entity = context->entity; *static_cast(out_component_data) = view.template get(entity); } @@ -146,22 +139,18 @@ auto context_update( const void* in_component_data, auto& view ) -> void { - using ecsact::entt::component_updated; using ecsact::entt::detail::exec_beforechange_storage; // TODO(Kelwan): for remove, beforeremove_storage - auto entity = context->entity; - auto& registry = *context->registry; + auto entity = context->entity; const auto& in_component = *static_cast(in_component_data); - - auto& current_component = view.template get(entity); auto& beforechange = view.template get>(entity); + auto& current_component = view.template get(entity); if(!beforechange.has_update_occurred) { beforechange.value = current_component; beforechange.has_update_occurred = true; - registry.template emplace_or_replace>(entity); } current_component = in_component; } diff --git a/rt_entt_codegen/BUILD.bazel b/rt_entt_codegen/BUILD.bazel index 2219a05..b5a95cd 100644 --- a/rt_entt_codegen/BUILD.bazel +++ b/rt_entt_codegen/BUILD.bazel @@ -12,6 +12,7 @@ cc_ecsact_codegen_plugin( "//rt_entt_codegen/core", "//rt_entt_codegen/shared:ecsact_entt_details", "//rt_entt_codegen/shared:util", + "@ecsact_lang_cpp//:cpp_codegen_plugin_util", "@ecsact_lang_cpp//:support", ], ) diff --git a/rt_entt_codegen/core/BUILD.bazel b/rt_entt_codegen/core/BUILD.bazel index 4691826..cd4b655 100644 --- a/rt_entt_codegen/core/BUILD.bazel +++ b/rt_entt_codegen/core/BUILD.bazel @@ -31,6 +31,7 @@ _CORE_CODEGEN_METHODS = { "//rt_entt_codegen/core/system_provider:association", "//rt_entt_codegen/core/system_provider:notify", "//rt_entt_codegen/core/system_provider:basic", + "//rt_entt_codegen/core/system_provider:parallel", "//rt_entt_codegen/core/system_provider", "@entt//:entt", "@ecsact_rt_entt//:lib", diff --git a/rt_entt_codegen/core/check_error.cc b/rt_entt_codegen/core/check_error.cc index 79c5ae1..5b89137 100644 --- a/rt_entt_codegen/core/check_error.cc +++ b/rt_entt_codegen/core/check_error.cc @@ -49,7 +49,7 @@ static auto print_check_add_component_error_template_specialization( auto printer = // method_printer{ctx, method_name} - .parameter("::entt::registry&", "registry") + .parameter("ecsact::entt::registry_t&", "registry") .parameter("::ecsact::entt::entity_id", "entity") .parameter(cpp_component_ident + " const&", "component") .return_type("ecsact_add_error"); @@ -82,7 +82,7 @@ static auto print_check_update_component_error_template_specialization( auto printer = // method_printer{ctx, method_name} - .parameter("::entt::registry&", "registry") + .parameter("ecsact::entt::registry_t&", "registry") .parameter("::ecsact::entt::entity_id", "entity") .parameter(cpp_component_ident + " const&", "component") .return_type("ecsact_update_error"); @@ -115,7 +115,7 @@ static auto print_check_action_error_template_specialization( auto printer = // method_printer{ctx, method_name} - .parameter("::entt::registry&", "registry") + .parameter("ecsact::entt::registry_t&", "registry") .parameter(cpp_action_ident + " const&", "action") .return_type("ecsact_execute_systems_error"); diff --git a/rt_entt_codegen/core/entity_matches.cc b/rt_entt_codegen/core/entity_matches.cc index 445bceb..a49e59e 100644 --- a/rt_entt_codegen/core/entity_matches.cc +++ b/rt_entt_codegen/core/entity_matches.cc @@ -29,7 +29,7 @@ auto ecsact::rt_entt_codegen::core::print_entity_match_fn( ctx.write("template<>\n"); auto printer = // method_printer{ctx, method_name} - .parameter("::entt::registry&", "reg") + .parameter("ecsact::entt::registry_t&", "reg") .parameter("ecsact::entt::entity_id", "entity") .return_type("bool"); diff --git a/rt_entt_codegen/core/execute_systems.cc b/rt_entt_codegen/core/execute_systems.cc index 4e216f0..618f970 100644 --- a/rt_entt_codegen/core/execute_systems.cc +++ b/rt_entt_codegen/core/execute_systems.cc @@ -22,7 +22,7 @@ auto ecsact::rt_entt_codegen::core::print_parallel_system_execute( ctx.write("template\n"); auto printer = // method_printer{ctx, "execute_parallel_cluster"} // - .parameter("::entt::registry&", "registry") + .parameter("ecsact::entt::registry_t&", "registry") .parameter("ecsact_system_execution_context*", "parent_context") .parameter("std::array", "system_arr") .return_type("void"); diff --git a/rt_entt_codegen/core/print_sys_exec.cc b/rt_entt_codegen/core/print_sys_exec.cc index 2c756d9..c81f1a3 100644 --- a/rt_entt_codegen/core/print_sys_exec.cc +++ b/rt_entt_codegen/core/print_sys_exec.cc @@ -16,12 +16,14 @@ #include "rt_entt_codegen/shared/comps_with_caps.hh" #include "rt_entt_codegen/shared/system_util.hh" #include "rt_entt_codegen/core/sys_exec/sys_exec.hh" +#include "rt_entt_codegen/shared/parallel.hh" #include "system_provider/system_provider.hh" #include "rt_entt_codegen/core/system_provider/lazy/lazy.hh" #include "system_provider/lazy/lazy.hh" #include "system_provider/association/association.hh" #include "system_provider/notify/notify.hh" #include "system_provider/basic/basic.hh" +#include "system_provider/parallel/parallel.hh" using capability_t = std::unordered_map; @@ -285,10 +287,19 @@ static auto print_system_execution_context( system_like_id_variant sys_like_id, const common_vars names, system_provider_t system_providers -) -> void { +) -> std::string { auto system_name = cpp_identifier(decl_full_name(sys_like_id)); - block(ctx, "struct : ecsact_system_execution_context ", [&] { + auto context_type_name = + ecsact::rt_entt_codegen::system_util::create_context_struct_name(sys_like_id + ); + + auto struct_header = std::format( + "struct {}: ecsact_system_execution_context ", + context_type_name + ); + + block(ctx, struct_header, [&] { ctx.write("view_t* view;\n"); for(const auto& provider : system_providers) { @@ -306,20 +317,9 @@ static auto print_system_execution_context( print_sys_exec_ctx_parent(ctx, names, system_providers); print_sys_exec_ctx_other(ctx, names, system_providers); }); - ctx.write("context;\n\n"); + ctx.write(";\n\n"); - ctx.write("context.registry = &", names.registry_var_name, ";\n"); - if(names.action_var_name) { - ctx.write("context.action_data = ", *names.action_var_name, ";\n\n"); - } - - ctx.write( - "context.id = ecsact_id_cast(::", - system_name, - "::id);\n" - ); - ctx.write("context.parent_ctx = ", names.parent_context_var_name, ";\n"); - ctx.write("context.view = &view;\n\n"); + return context_type_name; } static auto setup_system_providers(system_like_id_variant sys_like_id @@ -328,6 +328,8 @@ static auto setup_system_providers(system_like_id_variant sys_like_id using ecsact::rt_entt_codegen::core::provider::basic; using ecsact::rt_entt_codegen::core::provider::lazy; using ecsact::rt_entt_codegen::core::provider::notify; + using ecsact::rt_entt_codegen::core::provider::parallel; + using ecsact::rt_entt_codegen::parallel::can_entities_parallel; using ecsact::rt_entt_codegen::system_util::is_notify_system; assert(sys_like_id != system_like_id_variant{}); @@ -355,8 +357,16 @@ static auto setup_system_providers(system_like_id_variant sys_like_id system_providers.push_back(std::make_shared(sys_like_id)); } + if(can_entities_parallel(sys_like_id)) { + system_providers.push_back(std::make_shared(sys_like_id)); + } + system_providers.push_back(std::make_shared(sys_like_id)); + // NOTE: The basic provider must always be last. It's the only + // guaranteed provider and has fallbacks for exclusive functions + assert(dynamic_cast(system_providers.back().get()) != nullptr); + return system_providers; } @@ -389,7 +399,8 @@ static auto print_execute_systems( ctx.write("using view_t = decltype(view);\n"); - print_system_execution_context(ctx, sys_like_id, names, system_providers); + auto context_type_name = + print_system_execution_context(ctx, sys_like_id, names, system_providers); for(const auto& provider : system_providers) { provider->after_make_view_or_group(ctx, names); @@ -399,30 +410,49 @@ static auto print_execute_systems( provider->pre_entity_iteration(ctx, names); } - block(ctx, "for(ecsact::entt::entity_id entity : view)", [&] { - ctx.write("context.entity = entity;\n"); + auto context_init_provider = std::shared_ptr{}; + for(const auto& provider : system_providers) { + if(provider->provide_context_init(ctx, names, context_type_name) == + provider::HANDLED) { + context_init_provider = provider; + break; + } + } - ecsact::rt_entt_codegen::core::print_child_systems(ctx, names, sys_like_id); + for(auto provider : system_providers) { + auto result = provider->entity_iteration(ctx, names, [&] { + for(const auto& provider : system_providers) { + provider->pre_exec_system_impl(ctx, names); + } - for(const auto& provider : system_providers) { - provider->pre_exec_system_impl(ctx, names); - } + context_init_provider + ->pre_exec_system_impl_context_init(ctx, names, context_type_name); - auto result = std::ranges::find_if(system_providers, [&](auto provider) { - return provider->system_impl(ctx, names) == - handle_exclusive_provide::HANDLED; - }); + ecsact::rt_entt_codegen::core::print_child_systems( + ctx, + names, + sys_like_id + ); - if(result == system_providers.end()) { - throw std::logic_error("system_impl was not handled by providers"); - } + auto result = std::ranges::find_if(system_providers, [&](auto provider) { + return provider->system_impl(ctx, names) == + handle_exclusive_provide::HANDLED; + }); - for(const auto& provider : system_providers) { - provider->post_exec_system_impl(ctx, names); - } + if(result == system_providers.end()) { + throw std::logic_error("system_impl was not handled by providers"); + } - ctx.write("\n"); - }); + for(const auto& provider : system_providers) { + provider->post_exec_system_impl(ctx, names); + } + + ctx.write("\n"); + }); + if(result == handle_exclusive_provide::HANDLED) { + break; + } + } for(const auto& provider : system_providers) { provider->post_iteration(ctx, names); @@ -445,7 +475,7 @@ static auto print_trivial_system_like( ctx.write("template<>\n"); auto printer = // method_printer{ctx, "ecsact::entt::execute_system<::" + system_name + ">"} - .parameter("::entt::registry&", "registry") + .parameter("ecsact::entt::registry_t&", "registry") .parameter("ecsact_system_execution_context*", "parent_context") .parameter("const ecsact::entt::actions_map&", "actions_map") .return_type("void"); @@ -500,7 +530,7 @@ static auto print_execute_system_template_specialization( ctx.write("template<>\n"); auto printer = // method_printer{ctx, "ecsact::entt::execute_system<::" + system_name + ">"} - .parameter("::entt::registry&", "registry") + .parameter("ecsact::entt::registry_t&", "registry") .parameter("ecsact_system_execution_context*", "parent_context") .parameter("const ecsact::entt::actions_map&", "actions_map") .return_type("void"); @@ -550,7 +580,7 @@ static auto print_execute_actions_template_specialization( ctx.write("template<>\n"); auto printer = // method_printer{ctx, method_name} - .parameter("::entt::registry&", "registry") + .parameter("ecsact::entt::registry_t&", "registry") .parameter("ecsact_system_execution_context", "*parent_context") .parameter("const ecsact::entt::actions_map&", "actions_map") .return_type("void"); diff --git a/rt_entt_codegen/core/sorting_components.cc b/rt_entt_codegen/core/sorting_components.cc index f20ce59..3cba878 100644 --- a/rt_entt_codegen/core/sorting_components.cc +++ b/rt_entt_codegen/core/sorting_components.cc @@ -14,7 +14,7 @@ using ecsact::rt_entt_codegen::util::decl_cpp_ident; constexpr auto RECALC_COMPONENTS_HASH_DECL = R"cpp( template -static auto _recalc_sorting_hash(::entt::registry&) -> void; +static auto _recalc_sorting_hash(ecsact::entt::registry_t&) -> void; )cpp"; static auto print_system_entity_sorting_component_struct( @@ -35,7 +35,7 @@ static auto print_system_entity_sorting_component_struct( ctx.write("template<>\n"); auto printer = method_printer{ctx, "_recalc_sorting_hash<" + system_cpp_name + ">"} - .parameter("::entt::registry&", "reg") + .parameter("ecsact::entt::registry_t&", "reg") .return_type("void"); auto gen_comp_var_name = [](auto comp_id) -> std::string { diff --git a/rt_entt_codegen/core/system_markers.cc b/rt_entt_codegen/core/system_markers.cc index fef789c..b6280ab 100644 --- a/rt_entt_codegen/core/system_markers.cc +++ b/rt_entt_codegen/core/system_markers.cc @@ -29,7 +29,7 @@ auto ecsact::rt_entt_codegen::core::print_system_marker_add_fn( "ecsact::entt::detail::add_system_markers_if_needed<" + comp_cpp_ident + ">" } - .parameter("::entt::registry&", "reg") + .parameter("ecsact::entt::registry_t&", "reg") .parameter("ecsact::entt::entity_id", "entity") .return_type("void"); @@ -80,7 +80,7 @@ auto ecsact::rt_entt_codegen::core::print_system_marker_remove_fn( "ecsact::entt::detail::remove_system_markers_if_needed<" + comp_cpp_ident + ">" } - .parameter("::entt::registry&", "reg") + .parameter("ecsact::entt::registry_t&", "reg") .parameter("ecsact::entt::entity_id", "entity") .return_type("void"); @@ -109,7 +109,7 @@ auto ecsact::rt_entt_codegen::core::print_add_sys_beforestorage_fn( comp_name ) } - .parameter("::entt::registry&", "reg") + .parameter("ecsact::entt::registry_t&", "reg") .parameter("ecsact::entt::entity_id", "entity") .return_type("void"); diff --git a/rt_entt_codegen/core/system_provider/BUILD.bazel b/rt_entt_codegen/core/system_provider/BUILD.bazel index daf2852..c392f32 100644 --- a/rt_entt_codegen/core/system_provider/BUILD.bazel +++ b/rt_entt_codegen/core/system_provider/BUILD.bazel @@ -83,3 +83,18 @@ cc_library( "//rt_entt_codegen/shared:system_variant", ], ) + +cc_library( + name = "parallel", + srcs = ["parallel/parallel.cc"], + hdrs = ["parallel/parallel.hh"], + copts = copts, + visibility = ["//rt_entt_codegen/core:__pkg__"], + deps = [ + ":system_provider", + "//rt_entt_codegen/core/sys_exec", + "//rt_entt_codegen/shared:ecsact_entt_details", + "//rt_entt_codegen/shared:parallel", + "//rt_entt_codegen/shared:system_variant", + ], +) diff --git a/rt_entt_codegen/core/system_provider/basic/basic.cc b/rt_entt_codegen/core/system_provider/basic/basic.cc index 5b6432b..344f3ee 100644 --- a/rt_entt_codegen/core/system_provider/basic/basic.cc +++ b/rt_entt_codegen/core/system_provider/basic/basic.cc @@ -1,6 +1,9 @@ #include "basic.hh" +#include #include "ecsact/runtime/meta.hh" +#include "ecsact/lang-support/lang-cc.hh" +#include "ecsact/cpp_codegen_plugin_util.hh" #include "rt_entt_codegen/core/system_provider/system_ctx_functions.hh" using namespace ecsact::rt_entt_codegen::core; @@ -106,3 +109,49 @@ auto provider::basic::system_impl( ctx.write("system_impl(&context);\n"); return HANDLED; } + +auto provider::basic::entity_iteration( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::core::common_vars& names, + std::function iter_func +) -> handle_exclusive_provide { + using ecsact::cpp_codegen_plugin_util::block; + + block(ctx, "for(ecsact::entt::entity_id entity : view)", [&] { + iter_func(); + }); + return HANDLED; +} + +auto provider::basic::provide_context_init( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::core::common_vars& names, + std::string_view context_type_name +) -> handle_exclusive_provide { + ctx.write(std::format("{} context;\n\n", context_type_name)); + + auto system_name = + cc_lang_support::cpp_identifier(meta::decl_full_name(sys_like_id)); + + ctx.write("context.registry = &", names.registry_var_name, ";\n"); + if(names.action_var_name) { + ctx.write("context.action_data = ", *names.action_var_name, ";\n\n"); + } + + ctx.write( + "context.id = ecsact_id_cast(::", + system_name, + "::id);\n" + ); + ctx.write("context.parent_ctx = ", names.parent_context_var_name, ";\n"); + ctx.write("context.view = &view;\n\n"); + return HANDLED; +} + +auto provider::basic::pre_exec_system_impl_context_init( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::core::common_vars& names, + std::string_view context_type_name +) -> void { + ctx.write("context.entity = entity;\n"); +} diff --git a/rt_entt_codegen/core/system_provider/basic/basic.hh b/rt_entt_codegen/core/system_provider/basic/basic.hh index 1236c9e..3163071 100644 --- a/rt_entt_codegen/core/system_provider/basic/basic.hh +++ b/rt_entt_codegen/core/system_provider/basic/basic.hh @@ -66,11 +66,29 @@ public: const common_vars& names ) -> handle_exclusive_provide final; + auto entity_iteration( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::core::common_vars& names, + std::function iter_func + ) -> handle_exclusive_provide; + auto system_impl( ecsact::codegen_plugin_context& ctx, const common_vars& names ) -> handle_exclusive_provide final; + auto provide_context_init( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::core::common_vars& names, + std::string_view context_type_name + ) -> handle_exclusive_provide; + + auto pre_exec_system_impl_context_init( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::core::common_vars& names, + std::string_view context_type_name + ) -> void; + private: std::unordered_map sys_caps; diff --git a/rt_entt_codegen/core/system_provider/notify/notify.cc b/rt_entt_codegen/core/system_provider/notify/notify.cc index 1ec0b1e..7df8358 100644 --- a/rt_entt_codegen/core/system_provider/notify/notify.cc +++ b/rt_entt_codegen/core/system_provider/notify/notify.cc @@ -129,9 +129,6 @@ auto provider::notify::print_system_notify_views( } if(notify_setting == ECSACT_SYS_NOTIFY_ONUPDATE) { - auto component_updated_str = - std::format("ecsact::entt::component_updated<{}>", cpp_comp_name); - auto view_name = std::format("{}_update_view", comp_name); ecsact::rt_entt_codegen::util::make_view( @@ -139,7 +136,7 @@ auto provider::notify::print_system_notify_views( view_name, registry_name, system_details, - std::vector{component_updated_str}, + {}, std::vector{run_system_comp} ); diff --git a/rt_entt_codegen/core/system_provider/parallel/parallel.cc b/rt_entt_codegen/core/system_provider/parallel/parallel.cc new file mode 100644 index 0000000..a4da93e --- /dev/null +++ b/rt_entt_codegen/core/system_provider/parallel/parallel.cc @@ -0,0 +1,57 @@ +#include "parallel.hh" + +#include +#include "ecsact/lang-support/lang-cc.hh" +#include "ecsact/cpp_codegen_plugin_util.hh" + +using namespace ecsact::rt_entt_codegen::core; + +auto provider::parallel::entity_iteration( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::core::common_vars& names, + std::function iter_func +) -> handle_exclusive_provide { + using ecsact::cpp_codegen_plugin_util::block; + + block( + ctx, + "std::for_each(std::execution::par_unseq, view.begin(), " + "view.end(), [&](auto entity)", + [&] { iter_func(); } + ); + ctx.write(");\n"); + return HANDLED; +} + +auto provider::parallel::provide_context_init( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::core::common_vars& names, + std::string_view context_type_name +) -> handle_exclusive_provide { + return HANDLED; +} + +auto provider::parallel::pre_exec_system_impl_context_init( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::core::common_vars& names, + std::string_view context_type_name +) -> void { + ctx.write(std::format("{} context;\n\n", context_type_name)); + + auto system_name = + cc_lang_support::cpp_identifier(meta::decl_full_name(sys_like_id)); + + ctx.write("context.registry = &", names.registry_var_name, ";\n"); + if(names.action_var_name) { + ctx.write("context.action_data = ", *names.action_var_name, ";\n\n"); + } + + ctx.write( + "context.id = ecsact_id_cast(::", + system_name, + "::id);\n" + ); + ctx.write("context.parent_ctx = ", names.parent_context_var_name, ";\n"); + ctx.write("context.view = &view;\n\n"); + ctx.write("context.entity = entity;\n"); +} diff --git a/rt_entt_codegen/core/system_provider/parallel/parallel.hh b/rt_entt_codegen/core/system_provider/parallel/parallel.hh new file mode 100644 index 0000000..c850225 --- /dev/null +++ b/rt_entt_codegen/core/system_provider/parallel/parallel.hh @@ -0,0 +1,29 @@ +#pragma once + +#include "rt_entt_codegen/core/system_provider/system_provider.hh" +#include "rt_entt_codegen/core/sys_exec/sys_exec.hh" + +namespace ecsact::rt_entt_codegen::core::provider { +class parallel final : public system_provider { +public: + using system_provider::system_provider; + + auto entity_iteration( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::core::common_vars& names, + std::function iter_func + ) -> handle_exclusive_provide; + + auto provide_context_init( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::core::common_vars& names, + std::string_view context_type_name + ) -> handle_exclusive_provide; + + auto pre_exec_system_impl_context_init( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::core::common_vars& names, + std::string_view context_type_name + ) -> void; +}; +} // namespace ecsact::rt_entt_codegen::core::provider diff --git a/rt_entt_codegen/core/system_provider/system_provider.cc b/rt_entt_codegen/core/system_provider/system_provider.cc index 5fa3a7d..170bc3c 100644 --- a/rt_entt_codegen/core/system_provider/system_provider.cc +++ b/rt_entt_codegen/core/system_provider/system_provider.cc @@ -105,12 +105,35 @@ auto system_provider::pre_entity_iteration( ) -> void { } +auto system_provider::provide_context_init( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::core::common_vars& names, + std::string_view context_type_name +) -> handle_exclusive_provide { + return NOT_HANDLED; +} + +auto system_provider::entity_iteration( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::core::common_vars& names, + std::function iter_func +) -> handle_exclusive_provide { + return NOT_HANDLED; +} + auto system_provider::pre_exec_system_impl( ecsact::codegen_plugin_context& ctx, const common_vars& names ) -> void { } +auto system_provider::pre_exec_system_impl_context_init( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::core::common_vars& names, + std::string_view context_type_name +) -> void { +} + auto system_provider::system_impl( ecsact::codegen_plugin_context& ctx, const common_vars& names diff --git a/rt_entt_codegen/core/system_provider/system_provider.hh b/rt_entt_codegen/core/system_provider/system_provider.hh index 4b8599d..7918d87 100644 --- a/rt_entt_codegen/core/system_provider/system_provider.hh +++ b/rt_entt_codegen/core/system_provider/system_provider.hh @@ -1,8 +1,9 @@ #pragma once +#include #include #include -#include +#include #include "rt_entt_codegen/core/sys_exec/sys_exec.hh" #include "rt_entt_codegen/shared/system_variant.hh" @@ -39,6 +40,7 @@ public: ecsact::codegen_plugin_context& ctx, const ecsact::rt_entt_codegen::core::common_vars& names ) -> void; + [[nodiscard]] virtual auto context_function_action( ecsact::codegen_plugin_context& ctx, const ecsact::rt_entt_codegen::core::common_vars& names @@ -80,18 +82,40 @@ public: ecsact::codegen_plugin_context& ctx, const ecsact::rt_entt_codegen::core::common_vars& names ) -> void; + + virtual auto provide_context_init( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::core::common_vars& names, + std::string_view context_type_name + ) -> handle_exclusive_provide; + + [[nodiscard]] virtual auto entity_iteration( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::core::common_vars& names, + std::function iter_func + ) -> handle_exclusive_provide; + virtual auto pre_exec_system_impl( ecsact::codegen_plugin_context& ctx, const ecsact::rt_entt_codegen::core::common_vars& names ) -> void; + + virtual auto pre_exec_system_impl_context_init( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::core::common_vars& names, + std::string_view context_type_name + ) -> void; + virtual auto system_impl( ecsact::codegen_plugin_context& ctx, const ecsact::rt_entt_codegen::core::common_vars& names ) -> handle_exclusive_provide; + virtual auto post_exec_system_impl( ecsact::codegen_plugin_context& ctx, const ecsact::rt_entt_codegen::core::common_vars& names ) -> void; + virtual auto post_iteration( ecsact::codegen_plugin_context& ctx, const ecsact::rt_entt_codegen::core::common_vars& names diff --git a/rt_entt_codegen/rt_entt_codegen.cc b/rt_entt_codegen/rt_entt_codegen.cc index 5b2d7b5..a97ee07 100644 --- a/rt_entt_codegen/rt_entt_codegen.cc +++ b/rt_entt_codegen/rt_entt_codegen.cc @@ -4,11 +4,14 @@ #include "ecsact/codegen/plugin.h" #include "ecsact/codegen/plugin.hh" #include "ecsact/lang-support/lang-cc.hh" +#include "ecsact/cpp_codegen_plugin_util.hh" #include "rt_entt_codegen/core/core.hh" #include "rt_entt_codegen/shared/ecsact_entt_details.hh" #include "shared/util.hh" +using ecsact::cpp_codegen_plugin_util::block; + constexpr auto GENERATED_FILE_DISCLAIMER = R"( // GENERATED FILE - DO NOT EDIT )"; @@ -48,6 +51,7 @@ void ecsact_codegen_plugin( inc_header(ctx, "ecsact/entt/registry_util.hh"); inc_header(ctx, "ecsact/entt/detail/globals.hh"); inc_header(ctx, "ecsact/entt/detail/apply_pending.hh"); + inc_header(ctx, "ecsact/entt/detail/registry.hh"); inc_header(ctx, "ecsact/entt/detail/bytes.hh"); inc_header(ctx, "ecsact/entt/detail/hash.hh"); inc_header(ctx, "ecsact/entt/detail/hash.hh"); @@ -209,6 +213,24 @@ void ecsact_codegen_plugin( ctx.write("\n"); + for(auto comp_id : details.all_components) { + auto cpp_comp_name = cpp_identifier(decl_full_name(comp_id)); + block( + ctx, + std::format( + "template<> struct entt::component_traits<{}>", + cpp_comp_name + ), + [&] { + ctx.write("using type = ::", cpp_comp_name, ";\n"); + ctx.write("static constexpr bool in_place_delete = true;\n"); + ctx.write("static constexpr std::size_t page_size = ENTT_PACKED_PAGE;\n" + ); + } + ); + ctx.write(";\n"); + } + { // Print core Ecsact API methods using namespace ecsact::rt_entt_codegen; diff --git a/rt_entt_codegen/shared/parallel.cc b/rt_entt_codegen/shared/parallel.cc index 7e71005..7caa4d5 100644 --- a/rt_entt_codegen/shared/parallel.cc +++ b/rt_entt_codegen/shared/parallel.cc @@ -39,6 +39,166 @@ static auto is_capability_safe(ecsact_system_capability capability) -> bool { return (unsafe_caps & capability) == 0b0; } +auto ecsact::rt_entt_codegen::parallel::print_parallel_execution_cluster( + ecsact::codegen_plugin_context& ctx, + const std::vector>& + parallel_system_cluster +) -> void { + using ecsact::cc_lang_support::cpp_identifier; + + for(const auto& systems_to_parallel : parallel_system_cluster) { + if(systems_to_parallel.size() == 1) { + auto single_system_like_variant = systems_to_parallel.begin(); + + auto sync_sys_name = cpp_identifier(ecsact::meta::decl_full_name( + single_system_like_variant->get_sys_like_id() + )); + + if(single_system_like_variant->is_action()) { + ctx.write(std::format( + "ecsact::entt::execute_actions<{}>(registry, {}, " + "actions_map);\n", + sync_sys_name, + "nullptr" + )); + } + if(single_system_like_variant->is_system()) { + ctx.write(std::format( + "ecsact::entt::execute_system<{}>(registry, {}, " + "actions_map);\n", + sync_sys_name, + "nullptr" + )); + } + continue; + } + if(systems_to_parallel.size() == 0) { + } + + ctx.write("execute_parallel_cluster(registry, nullptr, "); + ctx.write(std::format( + "std::array {{\n", + systems_to_parallel.size() + )); + for(const auto system_like_id_variant : systems_to_parallel) { + auto cpp_decl_name = + cpp_identifier(ecsact::meta::decl_full_name(system_like_id_variant)); + + if(system_like_id_variant.is_action()) { + ctx.write( + "\texec_entry_t{&ecsact::entt::execute_actions<", + cpp_decl_name, + ">, actions_map},\n" + ); + } else if(system_like_id_variant.is_system()) { + ctx.write( + "\texec_entry_t{&ecsact::entt::execute_system<", + cpp_decl_name, + ">, actions_map},\n" + ); + } else { + ctx.write("// ??? unhandled ??? ", cpp_decl_name, "\n"); + } + } + ctx.write("});\n"); + } +} + +static auto is_capability_safe_entities( + const system_like_id_variant sys_like_id, + ecsact_system_capability capability +) -> bool { + if(!ecsact::meta::get_system_generates_ids(sys_like_id).empty()) { + return false; + } + + std::underlying_type_t unsafe_caps = + ECSACT_SYS_CAP_ADDS | ECSACT_SYS_CAP_REMOVES; + unsafe_caps &= ~(ECSACT_SYS_CAP_EXCLUDE | ECSACT_SYS_CAP_INCLUDE); + + return (unsafe_caps & capability) == 0b0; +} + +/* + * Checks if a parent system's entities can run in parallel with its child + * systems. + * Return true if the parent and child entities to have no components in common + */ +static auto can_parent_and_child_system_parallel( + const std::vector& child_system_ids, + const std::unordered_map& + capabilities +) -> bool { + using ecsact::meta::decl_full_name; + + for(const auto child_sys_id : child_system_ids) { + auto testing_sys_name = decl_full_name(child_sys_id); + + auto child_capabilities = ecsact::meta::system_capabilities(child_sys_id); + + for(const auto& [child_comp_id, child_capability] : child_capabilities) { + for(const auto& [comp_id, capability] : capabilities) { + if(comp_id == child_comp_id) { + if(!is_capability_safe(capability) || + !is_capability_safe(child_capability)) { + return false; + } + } + } + } + } + return true; +} + +auto ecsact::rt_entt_codegen::parallel::can_entities_parallel( + const system_like_id_variant sys_like_id +) -> bool { + using ecsact::meta::decl_full_name; + + auto capabilities = ecsact::meta::system_capabilities(sys_like_id); + auto testing_sys_name = decl_full_name(sys_like_id); + for(const auto& [comp_id, capability] : capabilities) { + if(!is_capability_safe_entities(sys_like_id, capability)) { + return false; + } + + auto other_fields = + ecsact::meta::system_association_fields(sys_like_id, comp_id); + + for(auto field_id : other_fields) { + auto other_capabilities = ecsact::meta::system_association_capabilities( + sys_like_id, + comp_id, + field_id + ); + + // NOTE(Kelwan): Association is currently not compatible with executing + // entities in parallel. + for([[maybe_unused]] const auto [other_comp_id, other_capability] : + other_capabilities) { + return false; + // if(!is_capability_safe_entities(sys_like_id, other_capability)) { + // return false; + // } + } + } + + if(sys_like_id.is_system()) { + int lazy_iteration_rate = + ecsact_meta_get_lazy_iteration_rate(sys_like_id.as_system()); + if(lazy_iteration_rate > 0) { + return false; + } + } + } + + auto child_ids = ecsact::meta::get_child_system_ids(sys_like_id); + if(!child_ids.empty()) { + return can_parent_and_child_system_parallel(child_ids, capabilities); + } + return true; +} + static auto loop_iterator( const std::vector& system_list, const std::vector::iterator begin, @@ -154,68 +314,7 @@ static auto loop_iterator( parallel_system_list.push_back(sys_like_id); } - parallel_system_cluster.push_back(parallel_system_list); -} - -auto ecsact::rt_entt_codegen::parallel::print_parallel_execution_cluster( - ecsact::codegen_plugin_context& ctx, - const std::vector>& - parallel_system_cluster -) -> void { - using ecsact::cc_lang_support::cpp_identifier; - - for(const auto& systems_to_parallel : parallel_system_cluster) { - if(systems_to_parallel.size() == 1) { - auto single_system_like_variant = systems_to_parallel.begin(); - - auto sync_sys_name = cpp_identifier(ecsact::meta::decl_full_name( - single_system_like_variant->get_sys_like_id() - )); - - if(single_system_like_variant->is_action()) { - ctx.write(std::format( - "ecsact::entt::execute_actions<{}>(registry, {}, " - "actions_map);\n", - sync_sys_name, - "nullptr" - )); - } - if(single_system_like_variant->is_system()) { - ctx.write(std::format( - "ecsact::entt::execute_system<{}>(registry, {}, " - "actions_map);\n", - sync_sys_name, - "nullptr" - )); - } - continue; - } - - ctx.write("execute_parallel_cluster(registry, nullptr, "); - ctx.write(std::format( - "std::array {{\n", - systems_to_parallel.size() - )); - for(const auto system_like_id_variant : systems_to_parallel) { - auto cpp_decl_name = - cpp_identifier(ecsact::meta::decl_full_name(system_like_id_variant)); - - if(system_like_id_variant.is_action()) { - ctx.write( - "\texec_entry_t{&ecsact::entt::execute_actions<", - cpp_decl_name, - ">, actions_map},\n" - ); - } else if(system_like_id_variant.is_system()) { - ctx.write( - "\texec_entry_t{&ecsact::entt::execute_system<", - cpp_decl_name, - ">, actions_map},\n" - ); - } else { - ctx.write("// ??? unhandled ??? ", cpp_decl_name, "\n"); - } - } - ctx.write("});\n"); + if(!parallel_system_list.empty()) { + parallel_system_cluster.push_back(parallel_system_list); } } diff --git a/rt_entt_codegen/shared/parallel.hh b/rt_entt_codegen/shared/parallel.hh index e50d8e4..7e163df 100644 --- a/rt_entt_codegen/shared/parallel.hh +++ b/rt_entt_codegen/shared/parallel.hh @@ -16,4 +16,10 @@ auto print_parallel_execution_cluster( const std::vector>& parallel_system_cluster ) -> void; + +/* + * Checks if the entities in a system can run in parallel + */ +auto can_entities_parallel(const system_like_id_variant sys_like_id) -> bool; + } // namespace ecsact::rt_entt_codegen::parallel diff --git a/rt_entt_codegen/shared/system_util.hh b/rt_entt_codegen/shared/system_util.hh index 410ad8f..0b51ecd 100644 --- a/rt_entt_codegen/shared/system_util.hh +++ b/rt_entt_codegen/shared/system_util.hh @@ -2,6 +2,7 @@ #include "ecsact/runtime/meta.hh" #include "ecsact/lang-support/lang-cc.hh" +#include "rt_entt_codegen/shared/system_variant.hh" namespace ecsact::rt_entt_codegen::system_util {