Skip to content

Commit

Permalink
feat: Add reactive systems
Browse files Browse the repository at this point in the history
* init, update and remove as initial features
* OnChange to be added later to finish spec
  • Loading branch information
Kelwan committed May 16, 2024
1 parent 3dba899 commit 607c94e
Show file tree
Hide file tree
Showing 17 changed files with 640 additions and 85 deletions.
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

0 comments on commit 607c94e

Please # to comment.