From f3be96261a494e36e7e52992de79d3ec6712fe24 Mon Sep 17 00:00:00 2001 From: Kelwan Date: Tue, 28 May 2024 10:33:08 -0700 Subject: [PATCH] initial commit --- MODULE.bazel | 2 +- rt_entt_codegen/core/BUILD.bazel | 1 + rt_entt_codegen/core/print_sys_exec.cc | 355 ++++++++-------------- rt_entt_codegen/core/sys_exec/BUILD.bazel | 16 + rt_entt_codegen/core/sys_exec/sys_exec.cc | 231 ++++++++++++++ rt_entt_codegen/core/sys_exec/sys_exec.hh | 120 ++++++++ rt_entt_codegen/core/system_notify.cc | 4 +- rt_entt_codegen/shared/parallel.hh | 2 + rt_entt_codegen/shared/system_util.cc | 4 +- rt_entt_codegen/shared/system_util.hh | 31 +- 10 files changed, 506 insertions(+), 260 deletions(-) create mode 100644 rt_entt_codegen/core/sys_exec/BUILD.bazel create mode 100644 rt_entt_codegen/core/sys_exec/sys_exec.cc create mode 100644 rt_entt_codegen/core/sys_exec/sys_exec.hh diff --git a/MODULE.bazel b/MODULE.bazel index 06f3eef9..e2f94abf 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -7,7 +7,7 @@ module( bazel_dep(name = "rules_cc", version = "0.0.9") bazel_dep(name = "bazel_skylib", version = "1.6.1") bazel_dep(name = "rules_ecsact", version = "0.5.2") -bazel_dep(name = "ecsact_runtime", version = "0.6.1") +bazel_dep(name = "ecsact_runtime", version = "0.6.2") bazel_dep(name = "ecsact_lang_cpp", version = "0.4.1") bazel_dep(name = "boost.mp11", version = "1.83.0.bzl.1") bazel_dep(name = "entt", version = "3.12.2") diff --git a/rt_entt_codegen/core/BUILD.bazel b/rt_entt_codegen/core/BUILD.bazel index 7b0eda33..e8d9c8d6 100644 --- a/rt_entt_codegen/core/BUILD.bazel +++ b/rt_entt_codegen/core/BUILD.bazel @@ -25,6 +25,7 @@ _CORE_CODEGEN_METHODS = { "//rt_entt_codegen/shared:sorting", "//rt_entt_codegen/shared:system_util", "//rt_entt_codegen/shared:parallel", + "//rt_entt_codegen/core/sys_exec", "@entt//:entt", "@ecsact_rt_entt//:lib", ], diff --git a/rt_entt_codegen/core/print_sys_exec.cc b/rt_entt_codegen/core/print_sys_exec.cc index cf0b31f9..83ada008 100644 --- a/rt_entt_codegen/core/print_sys_exec.cc +++ b/rt_entt_codegen/core/print_sys_exec.cc @@ -7,16 +7,19 @@ #include #include #include +#include #include "ecsact/runtime/meta.hh" #include "ecsact/runtime/common.h" #include "ecsact/lang-support/lang-cc.hh" #include "ecsact/cpp_codegen_plugin_util.hh" +#include "rt_entt_codegen/core/sys_exec/sys_exec.hh" #include "rt_entt_codegen/shared/ecsact_entt_details.hh" #include "rt_entt_codegen/shared/util.hh" #include "rt_entt_codegen/shared/comps_with_caps.hh" #include "rt_entt_codegen/shared/sorting.hh" #include "rt_entt_codegen/shared/system_util.hh" #include "rt_entt_codegen/shared/parallel.hh" +#include "rt_entt_codegen/core/sys_exec/sys_exec.hh" using capability_t = std::unordered_map; @@ -28,11 +31,10 @@ concept system_or_action = using ecsact::rt_entt_codegen::system_comps_with_caps; using ecsact::rt_entt_codegen::system_needs_sorted_entities; -template static auto print_sys_exec_ctx_action( - ecsact::codegen_plugin_context& ctx, - const ecsact::rt_entt_codegen::ecsact_entt_system_details& details, - T system_id + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::ecsact_entt_system_details& details, + const ecsact::rt_entt_codegen::core::print_execute_systems_options options ) -> void { using ecsact::cc_lang_support::cpp_identifier; using ecsact::meta::decl_full_name; @@ -43,8 +45,9 @@ static auto print_sys_exec_ctx_action( .parameter("void*", "out_action_data") .return_type("void final"); - if constexpr(std::is_same_v) { - auto action_name = cpp_identifier(decl_full_name(system_id)); + if(options.is_action()) { + auto action_name = + cpp_identifier(decl_full_name(options.get_sys_like_id())); ctx.write( "*static_cast<", @@ -575,33 +578,100 @@ static auto print_apply_pendings( } } -template - requires(!std::is_same_v< - ecsact_system_like_id, - std::remove_cvref_t>) -struct print_ecsact_entt_system_details_options { - SystemLikeID sys_like_id; - std::string system_name; - std::string registry_var_name; - std::string parent_context_var_name; - /// only set if system is an action - std::optional action_var_name; -}; +static auto print_other_contexts( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::ecsact_entt_system_details& details, + const ecsact::rt_entt_codegen::core::print_execute_systems_options options +) -> std::map { + using ecsact::cc_lang_support::cpp_identifier; + using ecsact::cpp_codegen_plugin_util::block; + using ecsact::meta::component_name; + using ecsact::meta::decl_full_name; + using ecsact::meta::get_child_system_ids; + using ecsact::rt_entt_codegen::ecsact_entt_system_details; + using ecsact::rt_entt_codegen::other_key; + using ecsact::rt_entt_codegen::system_util::create_context_struct_name; + using ecsact::rt_entt_codegen::system_util::create_context_var_name; + using ecsact::rt_entt_codegen::system_util::get_unique_view_name; + using ecsact::rt_entt_codegen::util::method_printer; -template - requires(!std::is_same_v< - ecsact_system_like_id, - std::remove_cvref_t>) -static auto print_ecsact_entt_system_details( - ecsact::codegen_plugin_context& ctx, - const ecsact::rt_entt_codegen::ecsact_entt_details& details, - const ecsact::rt_entt_codegen::ecsact_entt_system_details& sys_details, - const print_ecsact_entt_system_details_options options + std::map other_views; + + for(auto& assoc_detail : details.association_details) { + auto struct_name = create_context_struct_name(assoc_detail.component_id); + auto struct_header = struct_name + " : ecsact_system_execution_context "; + + auto view_name = get_unique_view_name(); + other_views.insert( + other_views.end(), + std::pair( + other_key{ + .component_like_id = assoc_detail.component_id, + .field_id = assoc_detail.field_id // + }, + view_name + ) + ); + + auto other_details = + ecsact_entt_system_details::from_capabilities(assoc_detail.capabilities); + + ecsact::rt_entt_codegen::util::make_view( + ctx, + view_name, + "registry", + other_details + ); + + ctx.write(std::format("using {}_t = decltype({});\n", view_name, view_name) + ); + + block(ctx, "struct " + struct_header, [&] { + using namespace std::string_literals; + using ecsact::rt_entt_codegen::util::decl_cpp_ident; + using std::views::transform; + + ctx.write(std::format("{}_t* view;\n", view_name)); + ctx.write("\n"); + print_sys_exec_ctx_action(ctx, other_details, options); + print_sys_exec_ctx_add(ctx, other_details, assoc_detail.capabilities); + print_sys_exec_ctx_remove( + ctx, + other_details, + assoc_detail.capabilities, + view_name + ); + print_sys_exec_ctx_get(ctx, other_details, view_name); + print_sys_exec_ctx_update(ctx, other_details, view_name); + print_sys_exec_ctx_has(ctx, other_details); + print_sys_exec_ctx_generate(ctx, other_details); + print_sys_exec_ctx_parent(ctx); + print_sys_exec_ctx_other(ctx, other_details); + }); + ctx.write(";\n\n"); + + auto type_name = cpp_identifier(decl_full_name(assoc_detail.component_id)); + auto context_name = create_context_var_name(assoc_detail.component_id); + + ctx.write(struct_name, " ", context_name, ";\n\n"); + + ctx.write(context_name, ".view = &", view_name, ";\n"); + ctx.write(context_name, ".parent_ctx = nullptr;\n\n"); + ctx.write(context_name, ".registry = &", options.registry_var_name, ";\n"); + } + + return other_views; +} + +static auto print_execute_systems( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::ecsact_entt_details& details, + const ecsact::rt_entt_codegen::ecsact_entt_system_details& sys_details, + const ecsact::rt_entt_codegen::core::print_execute_systems_options options ) -> void { using ecsact::cc_lang_support::cpp_identifier; using ecsact::cpp_codegen_plugin_util::block; using ecsact::meta::decl_full_name; - using ecsact::meta::get_child_system_ids; using ecsact::rt_entt_codegen::ecsact_entt_system_details; using ecsact::rt_entt_codegen::system_util::create_context_struct_name; using ecsact::rt_entt_codegen::system_util::create_context_var_name; @@ -609,19 +679,11 @@ static auto print_ecsact_entt_system_details( using ecsact::rt_entt_codegen::system_util::print_system_notify_views; using ecsact::rt_entt_codegen::util::method_printer; - constexpr auto is_system_id = - std::is_same_v>; - - auto sys_caps = ecsact::meta::system_capabilities(options.sys_like_id); + auto sys_caps = ecsact::meta::system_capabilities(options.get_sys_like_id()); auto lazy_iteration_rate = 0; - if constexpr(is_system_id) { - lazy_iteration_rate = ecsact_meta_get_lazy_iteration_rate( - static_cast(options.sys_like_id) - ); - } auto exec_start_label_name = - std::format("exec_start_{}_", static_cast(options.sys_like_id)); + std::format("exec_start_{}_", static_cast(options.get_sys_like_id())); auto pending_lazy_exec_struct = std::format( "::ecsact::entt::detail::pending_lazy_execution<::{}>", @@ -635,6 +697,12 @@ static auto print_ecsact_entt_system_details( auto additional_view_components = std::vector{}; + if(options.is_system()) { + lazy_iteration_rate = ecsact_meta_get_lazy_iteration_rate( + static_cast(options.get_sys_like_id()) + ); + } + if(lazy_iteration_rate > 0) { ctx.write( "constexpr auto lazy_iteration_rate_ = ", @@ -647,23 +715,23 @@ static auto print_ecsact_entt_system_details( } constexpr auto is_system = std::is_same_v< - std::remove_cvref_t, + std::remove_cvref_t, ecsact_system_id>; - if constexpr(is_system) { - if(system_needs_sorted_entities(options.sys_like_id)) { + if(options.is_system()) { + if(system_needs_sorted_entities(options.as_system())) { additional_view_components.push_back(system_sorting_struct_name); } } - if(is_notify_system(options.sys_like_id)) { + if(is_notify_system(options.get_sys_like_id())) { additional_view_components.push_back( std::format("ecsact::entt::detail::run_system<{}>", options.system_name) ); print_system_notify_views( ctx, sys_details, - options.sys_like_id, + options.get_sys_like_id(), options.registry_var_name ); } @@ -678,8 +746,8 @@ static auto print_ecsact_entt_system_details( ctx.write("using view_t = decltype(view);\n"); - if constexpr(is_system) { - if(system_needs_sorted_entities(options.sys_like_id)) { + if(options.is_system()) { + if(system_needs_sorted_entities(options.as_system())) { ctx.write("view.use<", system_sorting_struct_name, ">();\n"); } } @@ -698,7 +766,7 @@ static auto print_ecsact_entt_system_details( } ctx.write("\n"); - print_sys_exec_ctx_action(ctx, sys_details, options.sys_like_id); + print_sys_exec_ctx_action(ctx, sys_details, options); print_sys_exec_ctx_add(ctx, sys_details, sys_caps); print_sys_exec_ctx_remove(ctx, sys_details, sys_caps, "view"); print_sys_exec_ctx_get(ctx, sys_details, "view"); @@ -760,105 +828,13 @@ static auto print_ecsact_entt_system_details( ctx.write("context.entity = entity;\n"); - auto child_system_ids = get_child_system_ids(options.sys_like_id); - - std::vector child_system_like_ids{}; - - child_system_like_ids.resize(child_system_ids.size()); - - std::transform( - child_system_ids.begin(), - child_system_ids.end(), - child_system_like_ids.begin(), - [](auto system_id) { - return ecsact_id_cast(system_id); - } + ecsact::rt_entt_codegen::core::print_child_systems( + ctx, + details, + sys_details, + options ); - if(!child_system_like_ids.empty()) { - if(child_system_ids.size() == 1) { - // TODO(Kelwan): Make use case system agnostic when we support - // nested Action systems - // Issue: https://github.com/ecsact-dev/ecsact_parse/issues/154 - for(auto child_sys_id : get_child_system_ids(options.sys_like_id)) { - auto child_details = ecsact_entt_system_details::from_system_like( - ecsact_id_cast(child_sys_id) - ); - - auto child_system_name = cpp_identifier(decl_full_name(child_sys_id)); - - ctx.write( - "ecsact::entt::execute_system<::" + child_system_name + ">(", - options.registry_var_name, - ", &context, {});\n" - ); - } - } else { - auto parallel_system_cluster = - ecsact::rt_entt_codegen::parallel::get_parallel_execution_cluster( - ctx, - details, - child_system_like_ids - ); - - for(const auto& systems_to_parallel : parallel_system_cluster) { - if(systems_to_parallel.size() == 1) { - auto sync_sys_id = systems_to_parallel[0]; - - auto sync_sys_name = - cpp_identifier(ecsact::meta::decl_full_name(sync_sys_id)); - - if(details.is_action(sync_sys_id)) { - ctx.write(std::format( - "ecsact::entt::execute_actions<{}>(registry, {}, " - "actions_map);\n", - sync_sys_name, - "parent_context" - )); - } - if(details.is_system(sync_sys_id)) { - ctx.write(std::format( - "ecsact::entt::execute_system<{}>(registry, {}, " - "actions_map);\n", - sync_sys_name, - "parent_context" - )); - } - continue; - } - - ctx.write("execute_parallel_cluster(registry, parent_context, "); - ctx.write(std::format( - "std::array {{\n", - systems_to_parallel.size() - )); - for(const auto system_like_id : systems_to_parallel) { - auto cpp_decl_name = - cpp_identifier(ecsact::meta::decl_full_name(system_like_id)); - - if(details.is_action(system_like_id)) { - ctx.write( - "\texec_entry_t{&ecsact::entt::execute_actions<", - cpp_decl_name, - ">, actions_map},\n" - ); - } else if(details.is_system(system_like_id)) { - 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"); - } - } - } - - ctx.write("\n"); - if(!other_view_names.empty()) { ctx.write("auto found_assoc_entities = 0;\n"); } @@ -990,97 +966,11 @@ static auto print_ecsact_entt_system_details( print_apply_pendings( ctx, sys_details, - options.sys_like_id, + options.get_sys_like_id(), options.registry_var_name ); } -template -static auto print_other_contexts( - ecsact::codegen_plugin_context& ctx, - const ecsact::rt_entt_codegen::ecsact_entt_system_details& details, - const print_ecsact_entt_system_details_options options -) -> std::map { - using ecsact::cc_lang_support::cpp_identifier; - using ecsact::cpp_codegen_plugin_util::block; - using ecsact::meta::component_name; - using ecsact::meta::decl_full_name; - using ecsact::meta::get_child_system_ids; - using ecsact::rt_entt_codegen::ecsact_entt_system_details; - using ecsact::rt_entt_codegen::other_key; - using ecsact::rt_entt_codegen::system_util::create_context_struct_name; - using ecsact::rt_entt_codegen::system_util::create_context_var_name; - using ecsact::rt_entt_codegen::system_util::get_unique_view_name; - using ecsact::rt_entt_codegen::util::method_printer; - - std::map other_views; - - for(auto& assoc_detail : details.association_details) { - auto struct_name = create_context_struct_name(assoc_detail.component_id); - auto struct_header = struct_name + " : ecsact_system_execution_context "; - - auto view_name = get_unique_view_name(); - other_views.insert( - other_views.end(), - std::pair( - other_key{ - .component_like_id = assoc_detail.component_id, - .field_id = assoc_detail.field_id // - }, - view_name - ) - ); - - auto other_details = - ecsact_entt_system_details::from_capabilities(assoc_detail.capabilities); - - ecsact::rt_entt_codegen::util::make_view( - ctx, - view_name, - "registry", - other_details - ); - - ctx.write(std::format("using {}_t = decltype({});\n", view_name, view_name) - ); - - block(ctx, "struct " + struct_header, [&] { - using namespace std::string_literals; - using ecsact::rt_entt_codegen::util::decl_cpp_ident; - using std::views::transform; - - ctx.write(std::format("{}_t* view;\n", view_name)); - ctx.write("\n"); - print_sys_exec_ctx_action(ctx, other_details, options.sys_like_id); - print_sys_exec_ctx_add(ctx, other_details, assoc_detail.capabilities); - print_sys_exec_ctx_remove( - ctx, - other_details, - assoc_detail.capabilities, - view_name - ); - print_sys_exec_ctx_get(ctx, other_details, view_name); - print_sys_exec_ctx_update(ctx, other_details, view_name); - print_sys_exec_ctx_has(ctx, other_details); - print_sys_exec_ctx_generate(ctx, other_details); - print_sys_exec_ctx_parent(ctx); - print_sys_exec_ctx_other(ctx, other_details); - }); - ctx.write(";\n\n"); - - auto type_name = cpp_identifier(decl_full_name(assoc_detail.component_id)); - auto context_name = create_context_var_name(assoc_detail.component_id); - - ctx.write(struct_name, " ", context_name, ";\n\n"); - - ctx.write(context_name, ".view = &", view_name, ";\n"); - ctx.write(context_name, ".parent_ctx = nullptr;\n\n"); - ctx.write(context_name, ".registry = &", options.registry_var_name, ";\n"); - } - - return other_views; -} - static auto print_trivial_system_like( ecsact::codegen_plugin_context& ctx, const ecsact::rt_entt_codegen::ecsact_entt_system_details& details, @@ -1144,6 +1034,7 @@ static auto print_execute_system_template_specialization( using ecsact::cc_lang_support::cpp_identifier; using ecsact::cpp_codegen_plugin_util::block; using ecsact::meta::decl_full_name; + using ecsact::rt_entt_codegen::core::system_like_id_variant_t; using ecsact::rt_entt_codegen::system_util::is_trivial_system; using ecsact::rt_entt_codegen::util::method_printer; @@ -1174,7 +1065,7 @@ static auto print_execute_system_template_specialization( block(ctx, "if(system_impl == nullptr)", [&] { ctx.write("return;"); }); - print_ecsact_entt_system_details( + print_execute_systems( ctx, details, sys_details, @@ -1237,7 +1128,7 @@ static auto print_execute_actions_template_specialization( ); block(ctx, "for(auto action : actions)", [&] { - print_ecsact_entt_system_details( + print_execute_systems( ctx, details, sys_details, diff --git a/rt_entt_codegen/core/sys_exec/BUILD.bazel b/rt_entt_codegen/core/sys_exec/BUILD.bazel new file mode 100644 index 00000000..8ed692a7 --- /dev/null +++ b/rt_entt_codegen/core/sys_exec/BUILD.bazel @@ -0,0 +1,16 @@ +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//bazel:copts.bzl", "copts") + +cc_library( + name = "sys_exec", + srcs = ["sys_exec.cc"], + hdrs = ["sys_exec.hh"], + copts = copts, + visibility = ["//visibility:public"], + deps = [ + "//rt_entt_codegen/shared:ecsact_entt_details", + "//rt_entt_codegen/shared:parallel", + "//rt_entt_codegen/shared:util", + "@ecsact_lang_cpp//:cpp_codegen_plugin_util", + ], +) diff --git a/rt_entt_codegen/core/sys_exec/sys_exec.cc b/rt_entt_codegen/core/sys_exec/sys_exec.cc new file mode 100644 index 00000000..62ebdd19 --- /dev/null +++ b/rt_entt_codegen/core/sys_exec/sys_exec.cc @@ -0,0 +1,231 @@ +#include "sys_exec.hh" + +#include "rt_entt_codegen/shared/util.hh" +#include "rt_entt_codegen/shared/ecsact_entt_details.hh" + +static auto exec_start_label_name = std::string{}; + +static auto pending_lazy_exec_struct = std::string{}; + +static int32_t lazy_iteration_rate{}; + +auto ecsact::rt_entt_codegen::core::init_lazy( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::core::print_execute_systems_options options, + std::vector& additional_view_components +) -> void { + lazy_iteration_rate = 0; + + if(options.is_system()) { + lazy_iteration_rate = ecsact_meta_get_lazy_iteration_rate( + static_cast(options.get_sys_like_id()) + ); + } + + exec_start_label_name = + std::format("exec_start_{}_", static_cast(options.get_sys_like_id())); + + pending_lazy_exec_struct = std::format( + "::ecsact::entt::detail::pending_lazy_execution<::{}>", + options.system_name + ); + + if(lazy_iteration_rate > 0) { + ctx.write( + "constexpr auto lazy_iteration_rate_ = ", + lazy_iteration_rate, + ";\n\n" + ); + ctx.write("auto iteration_count_ = 0;\n\n"); + ctx.write(exec_start_label_name, ":\n"); + additional_view_components.push_back(pending_lazy_exec_struct); + } +} + +auto ecsact::rt_entt_codegen::core::sort_print_access_lazy( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::ecsact_entt_system_details& sys_details, + const ecsact::rt_entt_codegen::core::print_execute_systems_options options +) -> void { + if(lazy_iteration_rate > 0) { + using ecsact::cpp_codegen_plugin_util::block; + + auto system_sorting_struct_name = std::format( + "::ecsact::entt::detail::system_sorted<{}>", + options.system_name + ); + + ctx.write( + "// If this assertion triggers that's a ecsact_rt_entt codegen " + "failure\n" + ); + ctx.write("assert(iteration_count_ <= lazy_iteration_rate_);\n"); + block(ctx, "if(iteration_count_ < lazy_iteration_rate_)", [&] { + ctx.write( + "_recalc_sorting_hash<", + options.system_name, + ">(", + options.registry_var_name, + ");\n" + ); + ctx.write( + options.registry_var_name, + ".sort<", + system_sorting_struct_name, + ">([](const auto& a, const auto& b) { return a.hash < b.hash; });\n" + ); + + ecsact::rt_entt_codegen::util::make_view( + ctx, + "view_no_pending_lazy_", + options.registry_var_name, + sys_details + ); + + ctx.write("auto view_no_pending_lazy_count_ = 0;\n"); + + block( + ctx, + "for(ecsact::entt::entity_id entity : view_no_pending_lazy_)", + [&] { + ctx.write( + "// If this assertion triggers this is an indicator of a codegen " + "failure.\n" + "// Please report to " + "https://github.com/ecsact-dev/ecsact_rt_entt\n" + ); + ctx.write( + "assert(", + options.registry_var_name, + ".all_of<", + system_sorting_struct_name, + ">(entity));\n" + ); + ctx.write("view_no_pending_lazy_count_ += 1;\n"); + ctx.write( + options.registry_var_name, + ".emplace<", + pending_lazy_exec_struct, + ">(entity);\n" + ); + } + ); + + block( + ctx, + "if(view_no_pending_lazy_count_ >= lazy_iteration_rate_)", + [&] { ctx.write("goto ", exec_start_label_name, ";\n"); } + ); + }); + } +} + +auto ecsact::rt_entt_codegen::core::print_child_systems( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::ecsact_entt_details& details, + const ecsact::rt_entt_codegen::ecsact_entt_system_details& sys_details, + const ecsact::rt_entt_codegen::core::print_execute_systems_options options +) -> void { + using ecsact::cc_lang_support::cpp_identifier; + using ecsact::meta::decl_full_name; + using ecsact::meta::get_child_system_ids; + using ecsact::rt_entt_codegen::ecsact_entt_system_details; + + auto child_system_ids = + ecsact::meta::get_child_system_ids(options.get_sys_like_id()); + + std::vector child_system_like_ids{}; + + child_system_like_ids.resize(child_system_ids.size()); + + std::transform( + child_system_ids.begin(), + child_system_ids.end(), + child_system_like_ids.begin(), + [](auto system_id) { + return ecsact_id_cast(system_id); + } + ); + + if(child_system_ids.size() == 1) { + // TODO(Kelwan): Make use case system agnostic when we support + // nested Action systems + // Issue: https://github.com/ecsact-dev/ecsact_parse/issues/154 + for(auto child_sys_id : get_child_system_ids(options.get_sys_like_id())) { + auto child_details = ecsact_entt_system_details::from_system_like( + ecsact_id_cast(child_sys_id) + ); + + auto child_system_name = cpp_identifier(decl_full_name(child_sys_id)); + + ctx.write( + "ecsact::entt::execute_system<::" + child_system_name + ">(", + options.registry_var_name, + ", &context, {});\n" + ); + } + } else { + auto parallel_system_cluster = + ecsact::rt_entt_codegen::parallel::get_parallel_execution_cluster( + ctx, + details, + child_system_like_ids + ); + + for(const auto& systems_to_parallel : parallel_system_cluster) { + if(systems_to_parallel.size() == 1) { + auto sync_sys_id = systems_to_parallel[0]; + + auto sync_sys_name = + cpp_identifier(ecsact::meta::decl_full_name(sync_sys_id)); + + if(details.is_action(sync_sys_id)) { + ctx.write(std::format( + "ecsact::entt::execute_actions<{}>(registry, {}, " + "actions_map);\n", + sync_sys_name, + "parent_context" + )); + } + if(details.is_system(sync_sys_id)) { + ctx.write(std::format( + "ecsact::entt::execute_system<{}>(registry, {}, " + "actions_map);\n", + sync_sys_name, + "parent_context" + )); + } + continue; + } + + ctx.write("execute_parallel_cluster(registry, parent_context, "); + ctx.write(std::format( + "std::array {{\n", + systems_to_parallel.size() + )); + for(const auto system_like_id : systems_to_parallel) { + auto cpp_decl_name = + cpp_identifier(ecsact::meta::decl_full_name(system_like_id)); + + if(details.is_action(system_like_id)) { + ctx.write( + "\texec_entry_t{&ecsact::entt::execute_actions<", + cpp_decl_name, + ">, actions_map},\n" + ); + } else if(details.is_system(system_like_id)) { + 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"); + } + } + + ctx.write("\n"); +} diff --git a/rt_entt_codegen/core/sys_exec/sys_exec.hh b/rt_entt_codegen/core/sys_exec/sys_exec.hh new file mode 100644 index 00000000..4db20db7 --- /dev/null +++ b/rt_entt_codegen/core/sys_exec/sys_exec.hh @@ -0,0 +1,120 @@ +#pragma once + +#include +#include +#include +#include + +#include "rt_entt_codegen/shared/ecsact_entt_details.hh" +#include "ecsact/lang-support/lang-cc.hh" +#include "rt_entt_codegen/shared/parallel.hh" +#include "ecsact/cpp_codegen_plugin_util.hh" +#include "ecsact/codegen/plugin.hh" +#include "ecsact/runtime/meta.hh" + +namespace ecsact::rt_entt_codegen::core { + +using system_like_id_variant_t = + std::variant; + +struct print_execute_systems_options { + system_like_id_variant_t sys_like_id; + std::string system_name; + std::string registry_var_name; + std::string parent_context_var_name; + /// only set if system is an action + std::optional action_var_name; + + auto as_system() const -> ecsact_system_id { + return std::get(sys_like_id); + } + + auto as_action() const -> ecsact_action_id { + return std::get(sys_like_id); + } + + auto is_system() const -> bool { + return std::holds_alternative(sys_like_id); + } + + auto is_action() const -> bool { + return std::holds_alternative(sys_like_id); + } + + auto get_sys_like_id() const -> ecsact_system_like_id { + return std::visit( + [](auto&& arg) { return static_cast(arg); }, + sys_like_id + ); + } +}; + +auto init_lazy( + ecsact::codegen_plugin_context& ctx, + const print_execute_systems_options options, + std::vector& additional_view_components +) -> void; + +auto sort_print_access_lazy( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::ecsact_entt_system_details& sys_details, + const ecsact::rt_entt_codegen::core::print_execute_systems_options options +) -> void; + +auto print_system_execution_context( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::ecsact_entt_details& details, + const ecsact::rt_entt_codegen::ecsact_entt_system_details& sys_details, + const print_execute_systems_options options +) -> void; + +// using ecsact::cpp_codegen_plugin_util::block; + +// auto sys_caps = ecsact::meta::system_capabilities(options.sys_like_id); + +// block(ctx, "struct : ecsact_system_execution_context ", [&] { +// ctx.write("view_t* view;\n"); + +// ctx.write( +// "std::unordered_map " +// "other_contexts;\n\n" +// ); + +// if(options.action_var_name) { +// ctx.write("const void* action_data = nullptr;\n"); +// } + +// ctx.write("\n"); +// print_sys_exec_ctx_action(ctx, sys_details, options.sys_like_id); +// print_sys_exec_ctx_add(ctx, sys_details, sys_caps); +// print_sys_exec_ctx_remove(ctx, sys_details, sys_caps, "view"); +// print_sys_exec_ctx_get(ctx, sys_details, "view"); +// print_sys_exec_ctx_update(ctx, sys_details, "view"); +// print_sys_exec_ctx_has(ctx, sys_details); +// print_sys_exec_ctx_generate(ctx, sys_details); +// print_sys_exec_ctx_parent(ctx); +// print_sys_exec_ctx_other(ctx, sys_details); +// }); +// ctx.write("context;\n\n"); + +// ctx.write("context.registry = &", options.registry_var_name, ";\n"); +// if(options.action_var_name) { +// ctx.write("context.action_data = ", *options.action_var_name, ";\n\n"); +// } + +// ctx.write( +// "context.id = ecsact_id_cast(::", +// options.system_name, +// "::id);\n" +// ); +// ctx.write("context.parent_ctx = ", options.parent_context_var_name, ";\n"); +// ctx.write("context.view = &view;\n\n"); + +auto print_child_systems( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::ecsact_entt_details& details, + const ecsact::rt_entt_codegen::ecsact_entt_system_details& sys_details, + const ecsact::rt_entt_codegen::core::print_execute_systems_options options +) -> void; +} // namespace ecsact::rt_entt_codegen::core diff --git a/rt_entt_codegen/core/system_notify.cc b/rt_entt_codegen/core/system_notify.cc index d536f6ee..b116f945 100644 --- a/rt_entt_codegen/core/system_notify.cc +++ b/rt_entt_codegen/core/system_notify.cc @@ -18,7 +18,9 @@ auto ecsact::rt_entt_codegen::core::print_cleanup_system_notifies( .return_type("void"); for(auto system_id : details.all_systems) { - if(!system_util::is_notify_system(system_id)) { + if(!system_util::is_notify_system( + ecsact_id_cast(system_id) + )) { continue; } diff --git a/rt_entt_codegen/shared/parallel.hh b/rt_entt_codegen/shared/parallel.hh index dcf91f9f..13d39f84 100644 --- a/rt_entt_codegen/shared/parallel.hh +++ b/rt_entt_codegen/shared/parallel.hh @@ -1,3 +1,5 @@ +#pragma once + #include "ecsact/codegen/plugin.hh" #include "rt_entt_codegen/shared/ecsact_entt_details.hh" diff --git a/rt_entt_codegen/shared/system_util.cc b/rt_entt_codegen/shared/system_util.cc index d8497ac2..27b8114e 100644 --- a/rt_entt_codegen/shared/system_util.cc +++ b/rt_entt_codegen/shared/system_util.cc @@ -9,7 +9,7 @@ #include "ecsact/runtime/common.h" #include "rt_entt_codegen/shared/util.hh" -auto ecsact::rt_entt_codegen::system_util::detail::is_notify_system( +auto ecsact::rt_entt_codegen::system_util::is_notify_system( ecsact_system_like_id system_id ) -> bool { auto count = ecsact::meta::system_notify_settings_count(system_id); @@ -30,7 +30,7 @@ auto ecsact::rt_entt_codegen::system_util::detail::is_notify_system( return true; } -auto ecsact::rt_entt_codegen::system_util::detail::print_system_notify_views( +auto ecsact::rt_entt_codegen::system_util::print_system_notify_views( ecsact::codegen_plugin_context& ctx, const ecsact::rt_entt_codegen::ecsact_entt_system_details& details, ecsact_system_like_id system_id, diff --git a/rt_entt_codegen/shared/system_util.hh b/rt_entt_codegen/shared/system_util.hh index 488b70d2..8e6b9669 100644 --- a/rt_entt_codegen/shared/system_util.hh +++ b/rt_entt_codegen/shared/system_util.hh @@ -8,7 +8,13 @@ namespace ecsact::rt_entt_codegen::system_util { -namespace detail { +// template +// auto is_notify_system(SystemLikeID system_id) -> bool { +// return detail::is_notify_system( +// ecsact_id_cast(system_id) +// ); +// } + /* * Checks if a system uses notify and should implement the run_system * component in its execution @@ -24,29 +30,6 @@ auto print_system_notify_views( ecsact_system_like_id system_id, std::string registry_name ) -> void; -} // namespace detail - -template -auto is_notify_system(SystemLikeID system_id) -> bool { - return detail::is_notify_system( - ecsact_id_cast(system_id) - ); -} - -template -auto print_system_notify_views( - ecsact::codegen_plugin_context& ctx, - const ecsact::rt_entt_codegen::ecsact_entt_system_details& details, - SystemLikeID system_id, - std::string registry_name -) -> void { - detail::print_system_notify_views( - ctx, - details, - ecsact_id_cast(system_id), - registry_name - ); -} auto is_trivial_system(ecsact_system_like_id system_id) -> bool;