Skip to content

feat: add reactive systems with init, update and remove as initial features #110

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ecsact/entt/detail/internal_markers.hh
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ struct system_sorted {
template<typename S>
struct pending_lazy_execution {};

template<typename S>
struct run_system {};

template<typename>
constexpr bool system_markers_unimplemented_by_codegen = false;

Expand Down
2 changes: 1 addition & 1 deletion ecsact/entt/event_markers.hh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct component_added {};
* Marker to indicate that a component has been changed during execution
*/
template<typename C>
struct component_changed {};
struct component_updated {};

/**
* Marker to indicate that a component has been removed
Expand Down
21 changes: 14 additions & 7 deletions ecsact/entt/wrapper/core.hh
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ inline auto update_component_exec_options( //

if(err == ECSACT_UPDATE_OK) {
reg.replace<C>(entity, *static_cast<const C*>(component_data));
reg.template emplace_or_replace<component_changed<C>>(entity);
reg.template emplace_or_replace<component_updated<C>>(entity);
}

return err;
Expand All @@ -174,7 +174,7 @@ auto remove_component(
reg.remove<detail::beforechange_storage<C>>(entity);
}
reg.template remove<component_added<C>>(entity);
reg.template remove<component_changed<C>>(entity);
reg.template remove<component_updated<C>>(entity);
reg.template emplace_or_replace<component_removed<C>>(entity);
ecsact::entt::detail::remove_system_markers_if_needed<C>(reg, entity);
}
Expand All @@ -200,7 +200,7 @@ auto remove_component_exec_options(

reg.template erase<C>(entity);
reg.template remove<component_added<C>>(entity);
reg.template remove<component_changed<C>>(entity);
reg.template remove<component_updated<C>>(entity);
reg.template emplace_or_replace<component_removed<C>>(entity);

if constexpr(!std::is_empty_v<C>) {
Expand Down Expand Up @@ -292,7 +292,7 @@ auto _trigger_update_component_event(
ecsact_registry_id registry_id,
ecsact::entt::detail::execution_events_collector& events_collector
) -> void {
using ecsact::entt::component_changed;
using ecsact::entt::component_updated;
using ecsact::entt::detail::beforechange_storage;

if(!events_collector.has_update_callback()) {
Expand All @@ -304,7 +304,7 @@ auto _trigger_update_component_event(
::entt::basic_view changed_view{
reg.template storage<C>(),
reg.template storage<beforechange_storage<C>>(),
reg.template storage<component_changed<C>>(),
reg.template storage<component_updated<C>>(),
};

for(ecsact::entt::entity_id entity : changed_view) {
Expand Down Expand Up @@ -379,10 +379,17 @@ inline auto clear_component(ecsact_registry_id registry_id) -> void {
auto& reg = ecsact::entt::get_registry(registry_id);

reg.clear<ecsact::entt::component_added<C>>();
reg.clear<ecsact::entt::component_changed<C>>();
reg.clear<ecsact::entt::component_updated<C>>();
reg.clear<ecsact::entt::component_removed<C>>();
}

template<typename S>
inline auto clear_notify_component(ecsact_registry_id registry_id) -> void {
auto& reg = ecsact::entt::get_registry(registry_id);

reg.clear<ecsact::entt::detail::run_system<S>>();
}

template<typename C>
inline auto prepare_component(ecsact_registry_id registry_id) -> void {
using namespace ecsact::entt;
Expand All @@ -395,7 +402,7 @@ inline auto prepare_component(ecsact_registry_id registry_id) -> void {

if constexpr(!std::is_empty_v<C>) {
reg.storage<detail::beforechange_storage<C>>();
reg.template storage<component_changed<C>>();
reg.template storage<component_updated<C>>();
}
}

Expand Down
12 changes: 6 additions & 6 deletions ecsact/entt/wrapper/dynamic.hh
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,16 @@ auto context_remove(
) -> void {
assert(ecsact_id_cast<ecsact_component_like_id>(C::id) == component_id);

using ecsact::entt::component_changed;
using ecsact::entt::component_removed;
using ecsact::entt::component_updated;
using ecsact::entt::detail::beforeremove_storage;
using ecsact::entt::detail::pending_remove;

auto entity = context->entity;
auto& registry = *context->registry;

registry.template remove<component_added<C>>(entity);
registry.template remove<component_changed<C>>(entity);
registry.template remove<component_updated<C>>(entity);
registry.template emplace_or_replace<pending_remove<C>>(entity);
registry.template emplace_or_replace<component_removed<C>>(entity);

Expand All @@ -110,13 +110,13 @@ auto component_remove_trivial(
::entt::registry& registry,
ecsact::entt::entity_id entity_id
) -> void {
using ecsact::entt::component_changed;
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<component_added<C>>(entity_id);
registry.template remove<component_changed<C>>(entity_id);
registry.template remove<component_updated<C>>(entity_id);
registry.template emplace_or_replace<pending_remove<C>>(entity_id);
registry.template emplace_or_replace<component_removed<C>>(entity_id);

Expand Down Expand Up @@ -150,7 +150,7 @@ auto context_update(
[[maybe_unused]] ecsact_component_like_id component_id,
const void* in_component_data
) -> void {
using ecsact::entt::component_changed;
using ecsact::entt::component_updated;
// TODO(Kelwan): for remove, beforeremove_storage

auto entity = context->entity;
Expand All @@ -160,7 +160,7 @@ auto context_update(

auto& current_component = registry.template get<C>(entity);
current_component = in_component;
registry.template emplace_or_replace<component_changed<C>>(entity);
registry.template emplace_or_replace<component_updated<C>>(entity);
}

template<typename C>
Expand Down
2 changes: 2 additions & 0 deletions rt_entt_codegen/core/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ _CORE_CODEGEN_METHODS = {
"print_sys_exec": [
"//rt_entt_codegen/shared:comps_with_caps",
"//rt_entt_codegen/shared:sorting",
"//rt_entt_codegen/shared:system_util",
"@entt//:entt",
"@ecsact_rt_entt//:lib",
],
Expand All @@ -32,6 +33,7 @@ _CORE_CODEGEN_METHODS = {
"system_markers": [
"//rt_entt_codegen/shared:sorting",
],
"system_notify": ["//rt_entt_codegen/shared:system_util"],
}

[cc_library(
Expand Down
5 changes: 5 additions & 0 deletions rt_entt_codegen/core/core.hh
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ auto print_system_marker_remove_fn(
const ecsact_entt_details& details
) -> void;

auto print_cleanup_system_notifies(
codegen_plugin_context& ctx,
const ecsact_entt_details& details
) -> void;

auto print_entity_match_fn(
codegen_plugin_context& ctx,
const ecsact_entt_details& details
Expand Down
1 change: 1 addition & 0 deletions rt_entt_codegen/core/execute_systems.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ auto ecsact::rt_entt_codegen::core::print_execute_systems( //
);
});
ctx.write("cleanup_component_events(registry_id);\n");
ctx.write("cleanup_system_notifies(registry_id);\n");
});

ctx.write("return ECSACT_EXEC_SYS_OK;");
Expand Down
88 changes: 24 additions & 64 deletions rt_entt_codegen/core/print_sys_exec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#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"

using capability_t =
std::unordered_map<ecsact_component_like_id, ecsact_system_capability>;
Expand Down Expand Up @@ -560,6 +561,10 @@ static auto print_ecsact_entt_system_details(
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;
using ecsact::rt_entt_codegen::system_util::is_notify_system;
using ecsact::rt_entt_codegen::system_util::print_system_notify_views;
using ecsact::rt_entt_codegen::util::method_printer;

constexpr auto is_system_id =
Expand Down Expand Up @@ -603,6 +608,18 @@ static auto print_ecsact_entt_system_details(
additional_view_components.push_back(system_sorting_struct_name);
}

if(is_notify_system(options.sys_like_id)) {
additional_view_components.push_back(
std::format("ecsact::entt::detail::run_system<{}>", options.system_name)
);
print_system_notify_views(
ctx,
details,
options.sys_like_id,
options.registry_var_name
);
}

ecsact::rt_entt_codegen::util::make_view(
ctx,
"view",
Expand Down Expand Up @@ -771,7 +788,8 @@ static auto print_ecsact_entt_system_details(

if(lazy_iteration_rate > 0) {
ctx.write(
"// If this assertion triggers that's a ecsact_rt_entt codegen failure\n"
"// 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_)", [&] {
Expand Down Expand Up @@ -828,31 +846,6 @@ static auto print_ecsact_entt_system_details(
);
}

static auto get_unique_view_name() -> std::string {
static int counter = 0;
return "view" + std::to_string(counter++);
}

template<typename ComponentLikeID>
static auto create_context_struct_name( //
ComponentLikeID component_like_id
) -> std::string {
using ecsact::cc_lang_support::c_identifier;
auto full_name =
c_identifier(ecsact::meta::decl_full_name(component_like_id));
return full_name + "Struct";
}

template<typename ComponentLikeID>
static auto create_context_var_name( //
ComponentLikeID component_like_id
) -> std::string {
using ecsact::cc_lang_support::c_identifier;
auto full_name =
c_identifier(ecsact::meta::decl_full_name(component_like_id));
return full_name + "_context";
}

template<typename SystemLikeID>
static auto print_other_contexts(
ecsact::codegen_plugin_context& ctx,
Expand All @@ -866,6 +859,9 @@ static auto print_other_contexts(
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_key, std::string> other_views;
Expand Down Expand Up @@ -928,44 +924,6 @@ static auto print_other_contexts(
return other_views;
}

static auto is_trivial_system(ecsact_system_like_id system_id) -> bool {
using ecsact::meta::get_field_ids;
using ecsact::meta::system_capabilities;

auto sys_capabilities = system_capabilities(system_id);

auto non_trivial_capabilities = std::array{
ECSACT_SYS_CAP_READONLY,
ECSACT_SYS_CAP_READWRITE,
ECSACT_SYS_CAP_WRITEONLY,
ECSACT_SYS_CAP_OPTIONAL_READONLY,
ECSACT_SYS_CAP_OPTIONAL_READWRITE,
ECSACT_SYS_CAP_OPTIONAL_WRITEONLY,
};

bool has_non_tag_adds = false;
bool has_read_write = false;
for(auto&& [comp_id, sys_cap] : sys_capabilities) {
if((ECSACT_SYS_CAP_ADDS & sys_cap) == ECSACT_SYS_CAP_ADDS) {
auto field_count =
ecsact_meta_count_fields(ecsact_id_cast<ecsact_composite_id>(comp_id));
if(field_count > 0) {
has_non_tag_adds = true;
}
}

for(auto non_trivial_cap : non_trivial_capabilities) {
if((non_trivial_cap & sys_cap) == sys_cap) {
has_read_write = true;
}
}
}
if(has_non_tag_adds || has_read_write) {
return false;
}
return true;
}

static auto print_trivial_system_like(
ecsact::codegen_plugin_context& ctx,
const ecsact::rt_entt_codegen::ecsact_entt_system_details& details,
Expand Down Expand Up @@ -1027,6 +985,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::system_util::is_trivial_system;

using ecsact::rt_entt_codegen::util::method_printer;

Expand Down Expand Up @@ -1076,6 +1035,7 @@ static auto print_execute_actions_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::system_util::is_trivial_system;
using ecsact::rt_entt_codegen::util::method_printer;

if(is_trivial_system(ecsact_id_cast<ecsact_system_like_id>(action_id))) {
Expand Down
1 change: 0 additions & 1 deletion rt_entt_codegen/core/system_markers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ auto ecsact::rt_entt_codegen::core::print_system_marker_remove_fn(
const ecsact_entt_details& details
) -> void {
for(auto comp : details.all_components) {
auto comp_like_id = ecsact_id_cast<ecsact_component_like_id>(comp);
auto comp_name = ecsact::meta::decl_full_name(comp);
auto comp_cpp_ident = cc_lang_support::cpp_identifier(comp_name);
auto sorting_structs_covered = std::set<ecsact_system_id>{};
Expand Down
38 changes: 38 additions & 0 deletions rt_entt_codegen/core/system_notify.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "rt_entt_codegen/core/core.hh"
#include "ecsact/lang-support/lang-cc.hh"
#include "ecsact/cpp_codegen_plugin_util.hh"
#include "rt_entt_codegen/shared/system_util.hh"

auto ecsact::rt_entt_codegen::core::print_cleanup_system_notifies(
codegen_plugin_context& ctx,
const ecsact_entt_details& details
) -> void {
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::util::method_printer;

auto printer = //
method_printer{ctx, "cleanup_system_notifies"}
.parameter("ecsact_registry_id", "registry_id")
.return_type("void");

for(auto system_id : details.all_systems) {
if(!system_util::is_notify_system(system_id)) {
continue;
}

auto system_name = cpp_identifier(decl_full_name(system_id));

ctx.write(
"ecsact::entt::wrapper::core::clear_notify_component<",
system_name,
">(registry_id);\n"
);
}
}

namespace ecsact::rt_entt_codegen::core::notify {
auto print_system_oninit() -> void {
}
} // namespace ecsact::rt_entt_codegen::core::notify
1 change: 1 addition & 0 deletions rt_entt_codegen/rt_entt_codegen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ void ecsact_codegen_plugin(
core::print_trigger_ecsact_events_all(ctx, details);
core::print_cleanup_ecsact_component_events(ctx, details);
core::print_execution_options(ctx, details);
core::print_cleanup_system_notifies(ctx, details);
core::print_execute_systems(ctx, details);
}
}
Loading