From da314e4feca71f3325df56977d8dffc183c8113e Mon Sep 17 00:00:00 2001 From: Kelwan Date: Mon, 3 Jun 2024 09:10:20 -0700 Subject: [PATCH 01/10] feat: entities running parallel on systems --- rt_entt_codegen/core/BUILD.bazel | 1 + rt_entt_codegen/core/print_sys_exec.cc | 70 ++++-- .../core/system_provider/BUILD.bazel | 15 ++ .../core/system_provider/basic/basic.cc | 14 ++ .../core/system_provider/basic/basic.hh | 6 + .../core/system_provider/parallel/parallel.cc | 22 ++ .../core/system_provider/parallel/parallel.hh | 17 ++ .../core/system_provider/system_provider.cc | 8 + .../core/system_provider/system_provider.hh | 7 +- rt_entt_codegen/shared/parallel.cc | 228 +++++++++++++----- rt_entt_codegen/shared/parallel.hh | 6 + rt_entt_codegen/shared/system_util.hh | 10 + test/parallel/BUILD.bazel | 2 + test/parallel/entity_parallel_test.ecsact | 16 ++ test/parallel/parallel_test.cc | 6 + test/parallel/parallel_test.ecsact | 2 + 16 files changed, 346 insertions(+), 84 deletions(-) create mode 100644 rt_entt_codegen/core/system_provider/parallel/parallel.cc create mode 100644 rt_entt_codegen/core/system_provider/parallel/parallel.hh create mode 100644 test/parallel/entity_parallel_test.ecsact 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/print_sys_exec.cc b/rt_entt_codegen/core/print_sys_exec.cc index 2c756d9..8537a98 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,9 +287,15 @@ 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)); + auto context_name = + ecsact::rt_entt_codegen::system_util::create_context_var_name(sys_like_id); + + auto context_header = + std::format("struct {}: ecsact_system_execution_context ", context_name); + block(ctx, "struct : ecsact_system_execution_context ", [&] { ctx.write("view_t* view;\n"); @@ -320,6 +328,8 @@ static auto print_system_execution_context( ); ctx.write("context.parent_ctx = ", names.parent_context_var_name, ";\n"); ctx.write("context.view = &view;\n\n"); + + return context_name; } static auto setup_system_providers(system_like_id_variant sys_like_id @@ -328,6 +338,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 +367,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 +409,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_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 +420,39 @@ 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"); + for(auto provider : system_providers) { + auto result = provider->entity_iteration(ctx, names, [&] { + ctx.write("context.entity = entity;\n"); - ecsact::rt_entt_codegen::core::print_child_systems(ctx, names, sys_like_id); + ecsact::rt_entt_codegen::core::print_child_systems( + ctx, + names, + sys_like_id + ); - 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); + } - auto result = std::ranges::find_if(system_providers, [&](auto provider) { - return provider->system_impl(ctx, names) == - handle_exclusive_provide::HANDLED; - }); + auto result = std::ranges::find_if(system_providers, [&](auto provider) { + return provider->system_impl(ctx, names) == + handle_exclusive_provide::HANDLED; + }); - if(result == system_providers.end()) { - throw std::logic_error("system_impl was not handled by providers"); - } + if(result == system_providers.end()) { + throw std::logic_error("system_impl was not handled by providers"); + } - for(const auto& provider : system_providers) { - provider->post_exec_system_impl(ctx, names); - } + for(const auto& provider : system_providers) { + provider->post_exec_system_impl(ctx, names); + } - ctx.write("\n"); - }); + ctx.write("\n"); + }); + if(result == handle_exclusive_provide::HANDLED) { + break; + } + } for(const auto& provider : system_providers) { provider->post_iteration(ctx, names); 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..96b878d 100644 --- a/rt_entt_codegen/core/system_provider/basic/basic.cc +++ b/rt_entt_codegen/core/system_provider/basic/basic.cc @@ -1,6 +1,7 @@ #include "basic.hh" #include "ecsact/runtime/meta.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 +107,16 @@ 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; +} diff --git a/rt_entt_codegen/core/system_provider/basic/basic.hh b/rt_entt_codegen/core/system_provider/basic/basic.hh index 1236c9e..00f6549 100644 --- a/rt_entt_codegen/core/system_provider/basic/basic.hh +++ b/rt_entt_codegen/core/system_provider/basic/basic.hh @@ -66,6 +66,12 @@ 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 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..65af568 --- /dev/null +++ b/rt_entt_codegen/core/system_provider/parallel/parallel.cc @@ -0,0 +1,22 @@ +#include "parallel.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; +} 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..176f9ca --- /dev/null +++ b/rt_entt_codegen/core/system_provider/parallel/parallel.hh @@ -0,0 +1,17 @@ +#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; +}; +} // 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..16fc94a 100644 --- a/rt_entt_codegen/core/system_provider/system_provider.cc +++ b/rt_entt_codegen/core/system_provider/system_provider.cc @@ -105,6 +105,14 @@ auto system_provider::pre_entity_iteration( ) -> void { } +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 diff --git a/rt_entt_codegen/core/system_provider/system_provider.hh b/rt_entt_codegen/core/system_provider/system_provider.hh index 4b8599d..7ce9d40 100644 --- a/rt_entt_codegen/core/system_provider/system_provider.hh +++ b/rt_entt_codegen/core/system_provider/system_provider.hh @@ -2,7 +2,7 @@ #include #include -#include +#include #include "rt_entt_codegen/core/sys_exec/sys_exec.hh" #include "rt_entt_codegen/shared/system_variant.hh" @@ -80,6 +80,11 @@ public: ecsact::codegen_plugin_context& ctx, const ecsact::rt_entt_codegen::core::common_vars& names ) -> void; + [[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 diff --git a/rt_entt_codegen/shared/parallel.cc b/rt_entt_codegen/shared/parallel.cc index 7e71005..a925993 100644 --- a/rt_entt_codegen/shared/parallel.cc +++ b/rt_entt_codegen/shared/parallel.cc @@ -10,6 +10,8 @@ #include "system_variant.hh" #include "ecsact/runtime/meta.hh" +#include + using ecsact::rt_entt_codegen::system_like_id_variant; static auto loop_iterator( @@ -39,6 +41,169 @@ 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)) { + std::cout << testing_sys_name << " failed on child systems check" + << std::endl; + 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)) { + std::cout << testing_sys_name << " failed on capability check" + << std::endl; + 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(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, @@ -156,66 +321,3 @@ static auto loop_iterator( } 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"); - } -} 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..89e24eb 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 "system_variant.hh" namespace ecsact::rt_entt_codegen::system_util { @@ -38,4 +39,13 @@ static auto create_context_var_name( // return full_name + "_context"; } +template +static auto create_context_var_name( // + system_like_id_variant sys_like_id +) -> std::string { + using ecsact::cc_lang_support::c_identifier; + auto full_name = c_identifier(ecsact::meta::decl_full_name(sys_like_id)); + return full_name + "_context"; +} + } // namespace ecsact::rt_entt_codegen::system_util diff --git a/test/parallel/BUILD.bazel b/test/parallel/BUILD.bazel index 06b9348..4e0abfb 100644 --- a/test/parallel/BUILD.bazel +++ b/test/parallel/BUILD.bazel @@ -6,6 +6,7 @@ load("@rules_ecsact//ecsact:defs.bzl", "ecsact_codegen") ecsact_codegen( name = "ecsact_cc_system_impl_srcs", srcs = [ + "entity_parallel_test.ecsact", "parallel_test.ecsact", ], output_directory = "_ecsact_cc_system_impl_srcs", @@ -17,6 +18,7 @@ ecsact_codegen( ecsact_entt_runtime( name = "runtime", srcs = [ + "entity_parallel_test.ecsact", "parallel_test.ecsact", ], ECSACT_ENTT_RUNTIME_PACKAGE = "::parallel_test::package", diff --git a/test/parallel/entity_parallel_test.ecsact b/test/parallel/entity_parallel_test.ecsact new file mode 100644 index 0000000..c832b3f --- /dev/null +++ b/test/parallel/entity_parallel_test.ecsact @@ -0,0 +1,16 @@ +package entity_test; + +component ComponentA { + i32 val; +} +component ComponentB { + i32 val; +} + +system ReadonlyParallelA { + readonly ComponentA; +} + +system ReadonlyParallelB { + readonly ComponentB; +} diff --git a/test/parallel/parallel_test.cc b/test/parallel/parallel_test.cc index 0a6aaed..ea16840 100644 --- a/test/parallel/parallel_test.cc +++ b/test/parallel/parallel_test.cc @@ -75,6 +75,12 @@ void parallel_test::ParentWithSharedComponentA::ChildWithSharedComponentA::impl( ) { } +void entity_test::ReadonlyParallelA::impl(context& ctx) { +} + +void entity_test::ReadonlyParallelB::impl(context& ctx) { +} + TEST(Parallel, RunEntitiesinParallel) { auto reg = ecsact::core::registry("RunEntitiesInParallel"); diff --git a/test/parallel/parallel_test.ecsact b/test/parallel/parallel_test.ecsact index 36fa64b..a4c881f 100644 --- a/test/parallel/parallel_test.ecsact +++ b/test/parallel/parallel_test.ecsact @@ -1,5 +1,7 @@ main package parallel_test; +import entity_test; + component ParallelA { i32 val; } From 21369f42c9f34f01b5dcc074369243cbb999b927 Mon Sep 17 00:00:00 2001 From: Kelwan Date: Wed, 5 Jun 2024 12:39:19 -0700 Subject: [PATCH 02/10] feat: custom allocator, add provider functions and context named --- build_recipe.yml | 3 + ecsact/entt/detail/allocator.hh | 91 +++++++++++++++++++ ecsact/entt/detail/apply_pending.hh | 4 +- ecsact/entt/detail/globals.hh | 3 +- ecsact/entt/detail/internal_markers.hh | 6 +- ecsact/entt/detail/registry.hh | 14 +++ .../entt/detail/system_execution_context.hh | 9 +- ecsact/entt/error_check.hh | 6 +- ecsact/entt/execution.hh | 11 ++- ecsact/entt/registry_util.hh | 5 +- ecsact/entt/wrapper/core.hh | 13 ++- ecsact/entt/wrapper/dynamic.hh | 10 +- rt_entt_codegen/BUILD.bazel | 1 + rt_entt_codegen/core/check_error.cc | 6 +- rt_entt_codegen/core/entity_matches.cc | 2 +- rt_entt_codegen/core/execute_systems.cc | 2 +- rt_entt_codegen/core/print_sys_exec.cc | 55 +++++++---- rt_entt_codegen/core/sorting_components.cc | 4 +- rt_entt_codegen/core/system_markers.cc | 6 +- .../core/system_provider/basic/basic.cc | 34 +++++++ .../core/system_provider/basic/basic.hh | 12 +++ .../core/system_provider/parallel/parallel.cc | 34 +++++++ .../core/system_provider/parallel/parallel.hh | 12 +++ .../core/system_provider/system_provider.cc | 15 +++ .../core/system_provider/system_provider.hh | 19 ++++ rt_entt_codegen/rt_entt_codegen.cc | 22 +++++ rt_entt_codegen/shared/parallel.cc | 4 +- rt_entt_codegen/shared/system_util.hh | 9 +- runtime/BUILD.bazel | 1 + runtime/allocator.cc | 11 +++ test/MODULE.bazel | 5 + 31 files changed, 372 insertions(+), 57 deletions(-) create mode 100644 ecsact/entt/detail/allocator.hh create mode 100644 ecsact/entt/detail/registry.hh create mode 100644 runtime/allocator.cc diff --git a/build_recipe.yml b/build_recipe.yml index fc1e578..09cff52 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 @@ -206,6 +208,7 @@ sources: - ./runtime/ecsact_rt_entt_core.cc - ./runtime/ecsact_rt_entt_dynamic.cc - ./runtime/hash.cc + - ./runtime/allocator.cc exports: # core diff --git a/ecsact/entt/detail/allocator.hh b/ecsact/entt/detail/allocator.hh new file mode 100644 index 0000000..bc26e86 --- /dev/null +++ b/ecsact/entt/detail/allocator.hh @@ -0,0 +1,91 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace ecsact::entt::detail { + +template +struct static_allocator_storage { + using buffer_t = std::array; + + std::unique_ptr buffer_ = std::make_unique(); + std::atomic_size_t offset_ = 0; +}; + +struct static_allocator_base { + static constexpr std::size_t static_size = 1e+8; + + static static_allocator_storage<1, static_size> storage1_; + static static_allocator_storage<4, static_size> storage4_; + static static_allocator_storage<8, static_size> storage8_; +}; + +template +struct static_allocator : static_allocator_base { + using value_type = T; + + static_allocator() = default; + static_allocator(const static_allocator& other) = default; + + static_allocator(static_allocator&& other) = default; + + template + static_allocator(const static_allocator&) { + } + + template + static_allocator(static_allocator&&) { + } + + [[nodiscard]] auto allocate(std::size_t n) noexcept -> T* { + constexpr auto alignment = std::alignment_of_v; + + if constexpr(alignment == 1) { + std::size_t alloc_start = storage1_.offset_.fetch_add(sizeof(T) * n); + return std::assume_aligned( + reinterpret_cast(storage1_.buffer_->data() + alloc_start) + ); + } + + if constexpr(alignment == 4) { + std::size_t alloc_start = storage4_.offset_.fetch_add(sizeof(T) * n); + return std::assume_aligned( + reinterpret_cast(storage4_.buffer_->data() + alloc_start) + ); + } + + if constexpr(alignment == 8) { + std::size_t alloc_start = storage8_.offset_.fetch_add(sizeof(T) * n); + return std::assume_aligned( + reinterpret_cast(storage8_.buffer_->data() + alloc_start) + ); + } + + static_assert( + alignment == 1 || alignment == 4 || alignment == 8, + "Missing support for alignment" + ); + } + + auto deallocate(T* p, std::size_t n) noexcept -> void { + } +}; + +template +auto operator==(const static_allocator&, const static_allocator&) + -> bool { + return true; +} + +template +auto operator!=(const static_allocator&, const static_allocator&) + -> bool { + return false; +} + +} // namespace ecsact::entt::detail 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..ac06e9d --- /dev/null +++ b/ecsact/entt/detail/registry.hh @@ -0,0 +1,14 @@ +#pragma once + +#include "entt/entity/registry.hpp" +#include "ecsact/entt/detail/allocator.hh" + +namespace ecsact::entt { + +using registry_t = ::entt:: + basic_registry<::entt::entity, detail::static_allocator<::entt::entity>>; +} + +// using registry_t = ::entt:: +// basic_registry<::entt::entity, detail::static_allocator<::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/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..9d34877 100644 --- a/ecsact/entt/wrapper/core.hh +++ b/ecsact/entt/wrapper/core.hh @@ -404,9 +404,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 +422,7 @@ inline auto prepare_system(ecsact_registry_id registry_id) -> void { reg.template storage>(); reg.template storage>(); + reg.template storage>(); } template @@ -435,8 +440,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..4b9353d 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; @@ -100,9 +100,9 @@ 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; 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/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 8537a98..d3a9cff 100644 --- a/rt_entt_codegen/core/print_sys_exec.cc +++ b/rt_entt_codegen/core/print_sys_exec.cc @@ -290,13 +290,16 @@ static auto print_system_execution_context( ) -> std::string { auto system_name = cpp_identifier(decl_full_name(sys_like_id)); - auto context_name = - ecsact::rt_entt_codegen::system_util::create_context_var_name(sys_like_id); + auto context_type_name = + ecsact::rt_entt_codegen::system_util::create_context_struct_name(sys_like_id + ); - auto context_header = - std::format("struct {}: ecsact_system_execution_context ", context_name); + auto struct_header = std::format( + "struct {}: ecsact_system_execution_context ", + context_type_name + ); - block(ctx, "struct : ecsact_system_execution_context ", [&] { + block(ctx, struct_header, [&] { ctx.write("view_t* view;\n"); for(const auto& provider : system_providers) { @@ -314,7 +317,17 @@ 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"); + + return context_type_name; +} + +static auto print_system_context_init_vars( + ecsact::codegen_plugin_context& ctx, + system_like_id_variant sys_like_id, + const common_vars names +) -> void { + auto system_name = cpp_identifier(decl_full_name(sys_like_id)); ctx.write("context.registry = &", names.registry_var_name, ";\n"); if(names.action_var_name) { @@ -328,8 +341,6 @@ static auto print_system_execution_context( ); ctx.write("context.parent_ctx = ", names.parent_context_var_name, ";\n"); ctx.write("context.view = &view;\n\n"); - - return context_name; } static auto setup_system_providers(system_like_id_variant sys_like_id @@ -409,7 +420,7 @@ static auto print_execute_systems( ctx.write("using view_t = decltype(view);\n"); - auto context_name = + auto context_type_name = print_system_execution_context(ctx, sys_like_id, names, system_providers); for(const auto& provider : system_providers) { @@ -420,9 +431,23 @@ static auto print_execute_systems( provider->pre_entity_iteration(ctx, names); } + 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; + } + } + for(auto provider : system_providers) { auto result = provider->entity_iteration(ctx, names, [&] { - ctx.write("context.entity = entity;\n"); + 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); ecsact::rt_entt_codegen::core::print_child_systems( ctx, @@ -430,10 +455,6 @@ static auto print_execute_systems( sys_like_id ); - for(const auto& provider : system_providers) { - provider->pre_exec_system_impl(ctx, names); - } - auto result = std::ranges::find_if(system_providers, [&](auto provider) { return provider->system_impl(ctx, names) == handle_exclusive_provide::HANDLED; @@ -475,7 +496,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"); @@ -530,7 +551,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"); @@ -580,7 +601,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/basic/basic.cc b/rt_entt_codegen/core/system_provider/basic/basic.cc index 96b878d..4e5263b 100644 --- a/rt_entt_codegen/core/system_provider/basic/basic.cc +++ b/rt_entt_codegen/core/system_provider/basic/basic.cc @@ -1,6 +1,7 @@ #include "basic.hh" #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" @@ -120,3 +121,36 @@ auto provider::basic::entity_iteration( }); 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 00f6549..3163071 100644 --- a/rt_entt_codegen/core/system_provider/basic/basic.hh +++ b/rt_entt_codegen/core/system_provider/basic/basic.hh @@ -77,6 +77,18 @@ public: 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/parallel/parallel.cc b/rt_entt_codegen/core/system_provider/parallel/parallel.cc index 65af568..a7be66a 100644 --- a/rt_entt_codegen/core/system_provider/parallel/parallel.cc +++ b/rt_entt_codegen/core/system_provider/parallel/parallel.cc @@ -1,5 +1,6 @@ #include "parallel.hh" +#include "ecsact/lang-support/lang-cc.hh" #include "ecsact/cpp_codegen_plugin_util.hh" using namespace ecsact::rt_entt_codegen::core; @@ -20,3 +21,36 @@ auto provider::parallel::entity_iteration( 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 index 176f9ca..c850225 100644 --- a/rt_entt_codegen/core/system_provider/parallel/parallel.hh +++ b/rt_entt_codegen/core/system_provider/parallel/parallel.hh @@ -13,5 +13,17 @@ public: 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 16fc94a..170bc3c 100644 --- a/rt_entt_codegen/core/system_provider/system_provider.cc +++ b/rt_entt_codegen/core/system_provider/system_provider.cc @@ -105,6 +105,14 @@ 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, @@ -119,6 +127,13 @@ auto system_provider::pre_exec_system_impl( ) -> 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 7ce9d40..7918d87 100644 --- a/rt_entt_codegen/core/system_provider/system_provider.hh +++ b/rt_entt_codegen/core/system_provider/system_provider.hh @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -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,23 +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 a925993..d5a7e10 100644 --- a/rt_entt_codegen/shared/parallel.cc +++ b/rt_entt_codegen/shared/parallel.cc @@ -319,5 +319,7 @@ static auto loop_iterator( parallel_system_list.push_back(sys_like_id); } - parallel_system_cluster.push_back(parallel_system_list); + if(!parallel_system_list.empty()) { + parallel_system_cluster.push_back(parallel_system_list); + } } diff --git a/rt_entt_codegen/shared/system_util.hh b/rt_entt_codegen/shared/system_util.hh index 89e24eb..550be0d 100644 --- a/rt_entt_codegen/shared/system_util.hh +++ b/rt_entt_codegen/shared/system_util.hh @@ -29,6 +29,14 @@ static auto create_context_struct_name( // return full_name + "Struct"; } +static auto create_context_struct_name( // + system_like_id_variant sys_like_id +) -> std::string { + using ecsact::cc_lang_support::c_identifier; + auto full_name = c_identifier(ecsact::meta::decl_full_name(sys_like_id)); + return full_name + "Struct"; +} + template static auto create_context_var_name( // ComponentLikeID component_like_id @@ -39,7 +47,6 @@ static auto create_context_var_name( // return full_name + "_context"; } -template static auto create_context_var_name( // system_like_id_variant sys_like_id ) -> std::string { diff --git a/runtime/BUILD.bazel b/runtime/BUILD.bazel index 672b2d9..540ec4d 100644 --- a/runtime/BUILD.bazel +++ b/runtime/BUILD.bazel @@ -2,6 +2,7 @@ package(default_visibility = ["//visibility:public"]) # keep sorted _srcs = [ + "allocator.cc", "ecsact_rt_entt_core.cc", "ecsact_rt_entt_dynamic.cc", "hash.cc", diff --git a/runtime/allocator.cc b/runtime/allocator.cc new file mode 100644 index 0000000..d845dd0 --- /dev/null +++ b/runtime/allocator.cc @@ -0,0 +1,11 @@ +#include "ecsact/entt/detail/allocator.hh" + +using ecsact::entt::detail::static_allocator_base; + +#define DEF_ALIGNED_STORAGE(n) \ + decltype(static_allocator_base::storage##n##_ \ + ) static_allocator_base::storage##n##_ = {} + +DEF_ALIGNED_STORAGE(1); +DEF_ALIGNED_STORAGE(4); +DEF_ALIGNED_STORAGE(8); diff --git a/test/MODULE.bazel b/test/MODULE.bazel index 5c51c23..c583be6 100644 --- a/test/MODULE.bazel +++ b/test/MODULE.bazel @@ -12,6 +12,11 @@ bazel_dep(name = "entt", version = "3.12.2") bazel_dep(name = "ecsact_cli", version = "0.3.9") bazel_dep(name = "boost.process", version = "1.83.0.bzl.2") +archive_override( + module_name = "entt", + urls = ["https://github.com/skypjack/entt/releases/download/v3.13.2/entt-v3.13.2.tar.gz"], +) + bazel_dep(name = "toolchains_llvm", version = "1.0.0", dev_dependency = True) bazel_dep(name = "hedron_compile_commands", dev_dependency = True) git_override( From 97debba515cf082084706e8fa4ffc80c1d033211 Mon Sep 17 00:00:00 2001 From: Kelwan Date: Fri, 7 Jun 2024 12:23:42 -0700 Subject: [PATCH 03/10] chore: remove component_updated marker --- ecsact/entt/event_markers.hh | 6 ------ ecsact/entt/wrapper/core.hh | 9 ++------- ecsact/entt/wrapper/dynamic.hh | 6 ------ rt_entt_codegen/core/system_provider/notify/notify.cc | 5 +---- test/runtime_test.cc | 2 ++ 5 files changed, 5 insertions(+), 23 deletions(-) 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/wrapper/core.hh b/ecsact/entt/wrapper/core.hh index 9d34877..478592b 100644 --- a/ecsact/entt/wrapper/core.hh +++ b/ecsact/entt/wrapper/core.hh @@ -10,6 +10,8 @@ #include "ecsact/entt/error_check.hh" #include "ecsact/entt/detail/execution_events_collector.hh" +#include + namespace ecsact::entt::wrapper::core { template @@ -156,7 +158,6 @@ inline auto update_component_exec_options( // if(err == ECSACT_UPDATE_OK) { reg.replace(entity, *static_cast(component_data)); - reg.template emplace_or_replace>(entity); } return err; @@ -177,7 +178,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 +203,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,7 +294,6 @@ 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::exec_beforechange_storage; if(!events_collector.has_update_callback()) { @@ -307,7 +305,6 @@ auto _trigger_update_component_event( ::entt::basic_view changed_view{ reg.template storage(), reg.template storage>(), - reg.template storage>(), }; for(ecsact::entt::entity_id entity : changed_view) { @@ -384,7 +381,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>(); } @@ -411,7 +407,6 @@ inline auto prepare_component(ecsact_registry_id registry_id) -> void { if constexpr(!std::is_empty_v) { reg.template storage>(); reg.template storage>(); - reg.template storage>(); } } diff --git a/ecsact/entt/wrapper/dynamic.hh b/ecsact/entt/wrapper/dynamic.hh index 4b9353d..e897ad1 100644 --- a/ecsact/entt/wrapper/dynamic.hh +++ b/ecsact/entt/wrapper/dynamic.hh @@ -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); @@ -105,12 +103,10 @@ auto component_remove_trivial( 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); @@ -146,7 +142,6 @@ 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 @@ -161,7 +156,6 @@ auto context_update( 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/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/test/runtime_test.cc b/test/runtime_test.cc index 13ee741..988b2b6 100644 --- a/test/runtime_test.cc +++ b/test/runtime_test.cc @@ -10,6 +10,8 @@ #include "ecsact/runtime/core.hh" #include "ecsact/runtime/dynamic.h" +#include + #include "runtime_test.ecsact.hh" #include "runtime_test.ecsact.systems.hh" From 155e4229ec299ded3ddae0b0b3c195f503241c3a Mon Sep 17 00:00:00 2001 From: Kelwan Date: Fri, 7 Jun 2024 13:41:48 -0700 Subject: [PATCH 04/10] chore: code cleanup --- ecsact/entt/detail/allocator.hh | 1 - ecsact/entt/detail/registry.hh | 4 ---- ecsact/entt/wrapper/core.hh | 2 -- rt_entt_codegen/core/print_sys_exec.cc | 21 ------------------- .../core/system_provider/basic/basic.cc | 1 + .../core/system_provider/parallel/parallel.cc | 1 + rt_entt_codegen/shared/system_util.hh | 16 -------------- test/parallel/BUILD.bazel | 2 -- test/parallel/entity_parallel_test.ecsact | 16 -------------- test/runtime_test.cc | 2 -- 10 files changed, 2 insertions(+), 64 deletions(-) delete mode 100644 test/parallel/entity_parallel_test.ecsact diff --git a/ecsact/entt/detail/allocator.hh b/ecsact/entt/detail/allocator.hh index bc26e86..e76c457 100644 --- a/ecsact/entt/detail/allocator.hh +++ b/ecsact/entt/detail/allocator.hh @@ -5,7 +5,6 @@ #include #include #include -#include namespace ecsact::entt::detail { diff --git a/ecsact/entt/detail/registry.hh b/ecsact/entt/detail/registry.hh index ac06e9d..1fd5c62 100644 --- a/ecsact/entt/detail/registry.hh +++ b/ecsact/entt/detail/registry.hh @@ -8,7 +8,3 @@ namespace ecsact::entt { using registry_t = ::entt:: basic_registry<::entt::entity, detail::static_allocator<::entt::entity>>; } - -// using registry_t = ::entt:: -// basic_registry<::entt::entity, detail::static_allocator<::entt::entity>>; -// } diff --git a/ecsact/entt/wrapper/core.hh b/ecsact/entt/wrapper/core.hh index 478592b..bb448e8 100644 --- a/ecsact/entt/wrapper/core.hh +++ b/ecsact/entt/wrapper/core.hh @@ -10,8 +10,6 @@ #include "ecsact/entt/error_check.hh" #include "ecsact/entt/detail/execution_events_collector.hh" -#include - namespace ecsact::entt::wrapper::core { template diff --git a/rt_entt_codegen/core/print_sys_exec.cc b/rt_entt_codegen/core/print_sys_exec.cc index d3a9cff..c81f1a3 100644 --- a/rt_entt_codegen/core/print_sys_exec.cc +++ b/rt_entt_codegen/core/print_sys_exec.cc @@ -322,27 +322,6 @@ static auto print_system_execution_context( return context_type_name; } -static auto print_system_context_init_vars( - ecsact::codegen_plugin_context& ctx, - system_like_id_variant sys_like_id, - const common_vars names -) -> void { - auto system_name = cpp_identifier(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"); -} - static auto setup_system_providers(system_like_id_variant sys_like_id ) -> system_provider_t { using ecsact::rt_entt_codegen::core::provider::association; diff --git a/rt_entt_codegen/core/system_provider/basic/basic.cc b/rt_entt_codegen/core/system_provider/basic/basic.cc index 4e5263b..344f3ee 100644 --- a/rt_entt_codegen/core/system_provider/basic/basic.cc +++ b/rt_entt_codegen/core/system_provider/basic/basic.cc @@ -1,5 +1,6 @@ #include "basic.hh" +#include #include "ecsact/runtime/meta.hh" #include "ecsact/lang-support/lang-cc.hh" #include "ecsact/cpp_codegen_plugin_util.hh" diff --git a/rt_entt_codegen/core/system_provider/parallel/parallel.cc b/rt_entt_codegen/core/system_provider/parallel/parallel.cc index a7be66a..a4da93e 100644 --- a/rt_entt_codegen/core/system_provider/parallel/parallel.cc +++ b/rt_entt_codegen/core/system_provider/parallel/parallel.cc @@ -1,5 +1,6 @@ #include "parallel.hh" +#include #include "ecsact/lang-support/lang-cc.hh" #include "ecsact/cpp_codegen_plugin_util.hh" diff --git a/rt_entt_codegen/shared/system_util.hh b/rt_entt_codegen/shared/system_util.hh index 550be0d..8bd9cf4 100644 --- a/rt_entt_codegen/shared/system_util.hh +++ b/rt_entt_codegen/shared/system_util.hh @@ -29,14 +29,6 @@ static auto create_context_struct_name( // return full_name + "Struct"; } -static auto create_context_struct_name( // - system_like_id_variant sys_like_id -) -> std::string { - using ecsact::cc_lang_support::c_identifier; - auto full_name = c_identifier(ecsact::meta::decl_full_name(sys_like_id)); - return full_name + "Struct"; -} - template static auto create_context_var_name( // ComponentLikeID component_like_id @@ -47,12 +39,4 @@ static auto create_context_var_name( // return full_name + "_context"; } -static auto create_context_var_name( // - system_like_id_variant sys_like_id -) -> std::string { - using ecsact::cc_lang_support::c_identifier; - auto full_name = c_identifier(ecsact::meta::decl_full_name(sys_like_id)); - return full_name + "_context"; -} - } // namespace ecsact::rt_entt_codegen::system_util diff --git a/test/parallel/BUILD.bazel b/test/parallel/BUILD.bazel index 4e0abfb..06b9348 100644 --- a/test/parallel/BUILD.bazel +++ b/test/parallel/BUILD.bazel @@ -6,7 +6,6 @@ load("@rules_ecsact//ecsact:defs.bzl", "ecsact_codegen") ecsact_codegen( name = "ecsact_cc_system_impl_srcs", srcs = [ - "entity_parallel_test.ecsact", "parallel_test.ecsact", ], output_directory = "_ecsact_cc_system_impl_srcs", @@ -18,7 +17,6 @@ ecsact_codegen( ecsact_entt_runtime( name = "runtime", srcs = [ - "entity_parallel_test.ecsact", "parallel_test.ecsact", ], ECSACT_ENTT_RUNTIME_PACKAGE = "::parallel_test::package", diff --git a/test/parallel/entity_parallel_test.ecsact b/test/parallel/entity_parallel_test.ecsact deleted file mode 100644 index c832b3f..0000000 --- a/test/parallel/entity_parallel_test.ecsact +++ /dev/null @@ -1,16 +0,0 @@ -package entity_test; - -component ComponentA { - i32 val; -} -component ComponentB { - i32 val; -} - -system ReadonlyParallelA { - readonly ComponentA; -} - -system ReadonlyParallelB { - readonly ComponentB; -} diff --git a/test/runtime_test.cc b/test/runtime_test.cc index 988b2b6..13ee741 100644 --- a/test/runtime_test.cc +++ b/test/runtime_test.cc @@ -10,8 +10,6 @@ #include "ecsact/runtime/core.hh" #include "ecsact/runtime/dynamic.h" -#include - #include "runtime_test.ecsact.hh" #include "runtime_test.ecsact.systems.hh" From 3e14084f25ab234d154a3272688555bebf63cfaa Mon Sep 17 00:00:00 2001 From: Kelwan Date: Fri, 7 Jun 2024 14:08:12 -0700 Subject: [PATCH 05/10] chore: remove static allocator --- build_recipe.yml | 1 - ecsact/entt/detail/allocator.hh | 90 --------------------------------- ecsact/entt/detail/registry.hh | 4 +- runtime/BUILD.bazel | 1 - runtime/allocator.cc | 11 ---- 5 files changed, 1 insertion(+), 106 deletions(-) delete mode 100644 ecsact/entt/detail/allocator.hh delete mode 100644 runtime/allocator.cc diff --git a/build_recipe.yml b/build_recipe.yml index 09cff52..be98340 100644 --- a/build_recipe.yml +++ b/build_recipe.yml @@ -208,7 +208,6 @@ sources: - ./runtime/ecsact_rt_entt_core.cc - ./runtime/ecsact_rt_entt_dynamic.cc - ./runtime/hash.cc - - ./runtime/allocator.cc exports: # core diff --git a/ecsact/entt/detail/allocator.hh b/ecsact/entt/detail/allocator.hh deleted file mode 100644 index e76c457..0000000 --- a/ecsact/entt/detail/allocator.hh +++ /dev/null @@ -1,90 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -namespace ecsact::entt::detail { - -template -struct static_allocator_storage { - using buffer_t = std::array; - - std::unique_ptr buffer_ = std::make_unique(); - std::atomic_size_t offset_ = 0; -}; - -struct static_allocator_base { - static constexpr std::size_t static_size = 1e+8; - - static static_allocator_storage<1, static_size> storage1_; - static static_allocator_storage<4, static_size> storage4_; - static static_allocator_storage<8, static_size> storage8_; -}; - -template -struct static_allocator : static_allocator_base { - using value_type = T; - - static_allocator() = default; - static_allocator(const static_allocator& other) = default; - - static_allocator(static_allocator&& other) = default; - - template - static_allocator(const static_allocator&) { - } - - template - static_allocator(static_allocator&&) { - } - - [[nodiscard]] auto allocate(std::size_t n) noexcept -> T* { - constexpr auto alignment = std::alignment_of_v; - - if constexpr(alignment == 1) { - std::size_t alloc_start = storage1_.offset_.fetch_add(sizeof(T) * n); - return std::assume_aligned( - reinterpret_cast(storage1_.buffer_->data() + alloc_start) - ); - } - - if constexpr(alignment == 4) { - std::size_t alloc_start = storage4_.offset_.fetch_add(sizeof(T) * n); - return std::assume_aligned( - reinterpret_cast(storage4_.buffer_->data() + alloc_start) - ); - } - - if constexpr(alignment == 8) { - std::size_t alloc_start = storage8_.offset_.fetch_add(sizeof(T) * n); - return std::assume_aligned( - reinterpret_cast(storage8_.buffer_->data() + alloc_start) - ); - } - - static_assert( - alignment == 1 || alignment == 4 || alignment == 8, - "Missing support for alignment" - ); - } - - auto deallocate(T* p, std::size_t n) noexcept -> void { - } -}; - -template -auto operator==(const static_allocator&, const static_allocator&) - -> bool { - return true; -} - -template -auto operator!=(const static_allocator&, const static_allocator&) - -> bool { - return false; -} - -} // namespace ecsact::entt::detail diff --git a/ecsact/entt/detail/registry.hh b/ecsact/entt/detail/registry.hh index 1fd5c62..0136693 100644 --- a/ecsact/entt/detail/registry.hh +++ b/ecsact/entt/detail/registry.hh @@ -1,10 +1,8 @@ #pragma once #include "entt/entity/registry.hpp" -#include "ecsact/entt/detail/allocator.hh" namespace ecsact::entt { -using registry_t = ::entt:: - basic_registry<::entt::entity, detail::static_allocator<::entt::entity>>; +using registry_t = ::entt::basic_registry<::entt::entity>; } diff --git a/runtime/BUILD.bazel b/runtime/BUILD.bazel index 540ec4d..672b2d9 100644 --- a/runtime/BUILD.bazel +++ b/runtime/BUILD.bazel @@ -2,7 +2,6 @@ package(default_visibility = ["//visibility:public"]) # keep sorted _srcs = [ - "allocator.cc", "ecsact_rt_entt_core.cc", "ecsact_rt_entt_dynamic.cc", "hash.cc", diff --git a/runtime/allocator.cc b/runtime/allocator.cc deleted file mode 100644 index d845dd0..0000000 --- a/runtime/allocator.cc +++ /dev/null @@ -1,11 +0,0 @@ -#include "ecsact/entt/detail/allocator.hh" - -using ecsact::entt::detail::static_allocator_base; - -#define DEF_ALIGNED_STORAGE(n) \ - decltype(static_allocator_base::storage##n##_ \ - ) static_allocator_base::storage##n##_ = {} - -DEF_ALIGNED_STORAGE(1); -DEF_ALIGNED_STORAGE(4); -DEF_ALIGNED_STORAGE(8); From 6f5c8528fb4c13dda7940d4944a8672df1df82de Mon Sep 17 00:00:00 2001 From: Kelwan Date: Fri, 7 Jun 2024 17:27:48 -0700 Subject: [PATCH 06/10] feat: exec_options working without comp updated marker --- ecsact/entt/wrapper/core.hh | 55 ++++++++++++++++++++++++++-------- ecsact/entt/wrapper/dynamic.hh | 11 ++----- 2 files changed, 45 insertions(+), 21 deletions(-) diff --git a/ecsact/entt/wrapper/core.hh b/ecsact/entt/wrapper/core.hh index bb448e8..f7cbde0 100644 --- a/ecsact/entt/wrapper/core.hh +++ b/ecsact/entt/wrapper/core.hh @@ -10,6 +10,8 @@ #include "ecsact/entt/error_check.hh" #include "ecsact/entt/detail/execution_events_collector.hh" +#include + namespace ecsact::entt::wrapper::core { template @@ -118,6 +120,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 +133,21 @@ 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& 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; } @@ -143,6 +158,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,10 +171,20 @@ inline auto update_component_exec_options( // *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& 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; } @@ -292,28 +319,30 @@ auto _trigger_update_component_event( ecsact_registry_id registry_id, ecsact::entt::detail::execution_events_collector& events_collector ) -> void { + 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>(), - }; + 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; } } } diff --git a/ecsact/entt/wrapper/dynamic.hh b/ecsact/entt/wrapper/dynamic.hh index e897ad1..7007384 100644 --- a/ecsact/entt/wrapper/dynamic.hh +++ b/ecsact/entt/wrapper/dynamic.hh @@ -127,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); } @@ -145,13 +142,11 @@ auto context_update( 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; From c33d4b9628c5de5606de71c915c72863589f8efb Mon Sep 17 00:00:00 2001 From: Kelwan Date: Fri, 7 Jun 2024 17:28:52 -0700 Subject: [PATCH 07/10] chore: remove iostream --- ecsact/entt/wrapper/core.hh | 2 -- rt_entt_codegen/shared/parallel.cc | 2 -- 2 files changed, 4 deletions(-) diff --git a/ecsact/entt/wrapper/core.hh b/ecsact/entt/wrapper/core.hh index f7cbde0..6de228e 100644 --- a/ecsact/entt/wrapper/core.hh +++ b/ecsact/entt/wrapper/core.hh @@ -10,8 +10,6 @@ #include "ecsact/entt/error_check.hh" #include "ecsact/entt/detail/execution_events_collector.hh" -#include - namespace ecsact::entt::wrapper::core { template diff --git a/rt_entt_codegen/shared/parallel.cc b/rt_entt_codegen/shared/parallel.cc index d5a7e10..d7fe920 100644 --- a/rt_entt_codegen/shared/parallel.cc +++ b/rt_entt_codegen/shared/parallel.cc @@ -10,8 +10,6 @@ #include "system_variant.hh" #include "ecsact/runtime/meta.hh" -#include - using ecsact::rt_entt_codegen::system_like_id_variant; static auto loop_iterator( From f415834e033824da994061b5823fbdef546b73b7 Mon Sep 17 00:00:00 2001 From: Kelwan Date: Fri, 7 Jun 2024 17:37:13 -0700 Subject: [PATCH 08/10] chore: remove more logs --- ecsact/entt/wrapper/core.hh | 8 +------- rt_entt_codegen/shared/parallel.cc | 4 ---- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/ecsact/entt/wrapper/core.hh b/ecsact/entt/wrapper/core.hh index 6de228e..901cd1d 100644 --- a/ecsact/entt/wrapper/core.hh +++ b/ecsact/entt/wrapper/core.hh @@ -136,13 +136,7 @@ inline auto update_component( // } 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; - } + auto& current_component = reg.template get(entity); current_component = in_component; diff --git a/rt_entt_codegen/shared/parallel.cc b/rt_entt_codegen/shared/parallel.cc index d7fe920..da9a9db 100644 --- a/rt_entt_codegen/shared/parallel.cc +++ b/rt_entt_codegen/shared/parallel.cc @@ -141,8 +141,6 @@ static auto can_parent_and_child_system_parallel( if(comp_id == child_comp_id) { if(!is_capability_safe(capability) || !is_capability_safe(child_capability)) { - std::cout << testing_sys_name << " failed on child systems check" - << std::endl; return false; } } @@ -161,8 +159,6 @@ auto ecsact::rt_entt_codegen::parallel::can_entities_parallel( 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)) { - std::cout << testing_sys_name << " failed on capability check" - << std::endl; return false; } From 88a7df90ec58d2d7f3b7c0c8324a7d26117a1c67 Mon Sep 17 00:00:00 2001 From: Kelwan Date: Fri, 7 Jun 2024 17:37:46 -0700 Subject: [PATCH 09/10] chore: full path name --- rt_entt_codegen/shared/system_util.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rt_entt_codegen/shared/system_util.hh b/rt_entt_codegen/shared/system_util.hh index 8bd9cf4..0b51ecd 100644 --- a/rt_entt_codegen/shared/system_util.hh +++ b/rt_entt_codegen/shared/system_util.hh @@ -2,7 +2,7 @@ #include "ecsact/runtime/meta.hh" #include "ecsact/lang-support/lang-cc.hh" -#include "system_variant.hh" +#include "rt_entt_codegen/shared/system_variant.hh" namespace ecsact::rt_entt_codegen::system_util { From 52dacff0e592b541530e4c4af29ec3287619e3f3 Mon Sep 17 00:00:00 2001 From: Kelwan Date: Mon, 10 Jun 2024 10:30:34 -0700 Subject: [PATCH 10/10] chore: remove entt override, linux warnings, and old tests --- rt_entt_codegen/shared/parallel.cc | 3 ++- test/MODULE.bazel | 5 ----- test/parallel/parallel_test.cc | 6 ------ test/parallel/parallel_test.ecsact | 2 -- 4 files changed, 2 insertions(+), 14 deletions(-) diff --git a/rt_entt_codegen/shared/parallel.cc b/rt_entt_codegen/shared/parallel.cc index da9a9db..7caa4d5 100644 --- a/rt_entt_codegen/shared/parallel.cc +++ b/rt_entt_codegen/shared/parallel.cc @@ -174,7 +174,8 @@ auto ecsact::rt_entt_codegen::parallel::can_entities_parallel( // NOTE(Kelwan): Association is currently not compatible with executing // entities in parallel. - for(const auto [other_comp_id, other_capability] : other_capabilities) { + 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; diff --git a/test/MODULE.bazel b/test/MODULE.bazel index c583be6..5c51c23 100644 --- a/test/MODULE.bazel +++ b/test/MODULE.bazel @@ -12,11 +12,6 @@ bazel_dep(name = "entt", version = "3.12.2") bazel_dep(name = "ecsact_cli", version = "0.3.9") bazel_dep(name = "boost.process", version = "1.83.0.bzl.2") -archive_override( - module_name = "entt", - urls = ["https://github.com/skypjack/entt/releases/download/v3.13.2/entt-v3.13.2.tar.gz"], -) - bazel_dep(name = "toolchains_llvm", version = "1.0.0", dev_dependency = True) bazel_dep(name = "hedron_compile_commands", dev_dependency = True) git_override( diff --git a/test/parallel/parallel_test.cc b/test/parallel/parallel_test.cc index ea16840..0a6aaed 100644 --- a/test/parallel/parallel_test.cc +++ b/test/parallel/parallel_test.cc @@ -75,12 +75,6 @@ void parallel_test::ParentWithSharedComponentA::ChildWithSharedComponentA::impl( ) { } -void entity_test::ReadonlyParallelA::impl(context& ctx) { -} - -void entity_test::ReadonlyParallelB::impl(context& ctx) { -} - TEST(Parallel, RunEntitiesinParallel) { auto reg = ecsact::core::registry("RunEntitiesInParallel"); diff --git a/test/parallel/parallel_test.ecsact b/test/parallel/parallel_test.ecsact index a4c881f..36fa64b 100644 --- a/test/parallel/parallel_test.ecsact +++ b/test/parallel/parallel_test.ecsact @@ -1,7 +1,5 @@ main package parallel_test; -import entity_test; - component ParallelA { i32 val; }