diff --git a/ecsact/entt/entity.hh b/ecsact/entt/entity.hh index 5aa754a..b5e80cf 100644 --- a/ecsact/entt/entity.hh +++ b/ecsact/entt/entity.hh @@ -1,63 +1,63 @@ -#pragma once - -#include -#include "ecsact/runtime/common.h" -#include - -namespace ecsact::entt { - -/** - * The Ecsact and EnTT entity IDs are supposed to be 1:1. This class serves to - * make using either trivial. - */ -class entity_id { - std::int32_t _id; - -public: - inline entity_id() { - } - - inline entity_id(::entt::entity entt_entity) - : _id(reinterpret_cast(entt_entity)) { - } - - inline entity_id(ecsact_entity_id ecsact_entity) - : _id(reinterpret_cast(ecsact_entity)) { - } - - entity_id(const entity_id&) = default; - entity_id(entity_id&&) = default; - - auto operator=(const entity_id&) -> entity_id& = default; - auto operator=(entity_id&&) -> entity_id& = default; - - auto operator<=>(const entity_id&) const = default; - - inline auto operator=(::entt::entity entt_entity) noexcept -> entity_id& { - _id = reinterpret_cast(entt_entity); - return *this; - } - - inline auto operator=(ecsact_entity_id ecsact_entity) noexcept -> entity_id& { - _id = reinterpret_cast(ecsact_entity); - return *this; - } - - inline operator ecsact_entity_id() const noexcept { - return reinterpret_cast(_id); - } - - inline operator ::entt::entity() const noexcept { - return reinterpret_cast(_id); - } - - [[nodiscard]] inline auto as_ecsact() const noexcept -> ecsact_entity_id { - return reinterpret_cast(_id); - } - - [[nodiscard]] inline auto as_entt() const noexcept -> ::entt::entity { - return reinterpret_cast(_id); - } -}; - -} // namespace ecsact::entt +#pragma once + +#include +#include "ecsact/runtime/common.h" +#include + +namespace ecsact::entt { + +/** + * The Ecsact and EnTT entity IDs are supposed to be 1:1. This class serves to + * make using either trivial. + */ +class entity_id { + std::int32_t _id; + +public: + inline entity_id() { + } + + inline entity_id(::entt::entity entt_entity) + : _id(reinterpret_cast(entt_entity)) { + } + + inline entity_id(ecsact_entity_id ecsact_entity) + : _id(reinterpret_cast(ecsact_entity)) { + } + + entity_id(const entity_id&) = default; + entity_id(entity_id&&) = default; + + auto operator=(const entity_id&) -> entity_id& = default; + auto operator=(entity_id&&) -> entity_id& = default; + + auto operator<=>(const entity_id&) const = default; + + inline auto operator=(::entt::entity entt_entity) noexcept -> entity_id& { + _id = reinterpret_cast(entt_entity); + return *this; + } + + inline auto operator=(ecsact_entity_id ecsact_entity) noexcept -> entity_id& { + _id = reinterpret_cast(ecsact_entity); + return *this; + } + + inline operator ecsact_entity_id() const noexcept { + return reinterpret_cast(_id); + } + + inline operator ::entt::entity() const noexcept { + return reinterpret_cast(_id); + } + + [[nodiscard]] inline auto as_ecsact() const noexcept -> ecsact_entity_id { + return reinterpret_cast(_id); + } + + [[nodiscard]] inline auto as_entt() const noexcept -> ::entt::entity { + return reinterpret_cast(_id); + } +}; + +} // namespace ecsact::entt diff --git a/ecsact/entt/error_check.hh b/ecsact/entt/error_check.hh index ac3a3d5..c14462a 100644 --- a/ecsact/entt/error_check.hh +++ b/ecsact/entt/error_check.hh @@ -1,64 +1,64 @@ -#pragma once - -#include -#include -#include -#include -#include -#include "ecsact/runtime/common.h" -#include "ecsact/runtime/core.h" -#include "entt/entity/registry.hpp" -#include "ecsact/entt/entity.hh" - -namespace ecsact::entt::detail { -template -constexpr bool error_check_unimplemented_by_codegen = false; -} - -namespace ecsact::entt { - -template -auto check_add_component_error( // - ::entt::registry&, - ::ecsact::entt::entity_id, - const C& -) -> ecsact_add_error { - static_assert(detail::error_check_unimplemented_by_codegen, R"( - ----------------------------------------------------------------------------- -| (!) CODEGEN ERROR | -| `check_add_component_error<>` template specialization cannot be found. This | -| is typically generated by ecsact_rt_entt_codegen. | - ----------------------------------------------------------------------------- -)"); -} - -template -auto check_update_component_error( // - ::entt::registry&, - ::ecsact::entt::entity_id, - const C& -) -> ecsact_update_error { - static_assert(detail::error_check_unimplemented_by_codegen, R"( - ----------------------------------------------------------------------------- -| (!) CODEGEN ERROR | -| `check_update_component_error<>` template specialization cannot be found. | -| This is typically generated by ecsact_rt_entt_codegen. | - ----------------------------------------------------------------------------- -)"); -} - -template -auto check_action_error( // - ::entt::registry&, - const A& -) -> ecsact_execute_systems_error { - static_assert(detail::error_check_unimplemented_by_codegen, R"( - ----------------------------------------------------------------------------- -| (!) CODEGEN ERROR | -| `check_action_error<>` template specialization cannot be found. | -| This is typically generated by ecsact_rt_entt_codegen. | - ----------------------------------------------------------------------------- -)"); -} - -} // namespace ecsact::entt +#pragma once + +#include +#include +#include +#include +#include +#include "ecsact/runtime/common.h" +#include "ecsact/runtime/core.h" +#include "entt/entity/registry.hpp" +#include "ecsact/entt/entity.hh" + +namespace ecsact::entt::detail { +template +constexpr bool error_check_unimplemented_by_codegen = false; +} + +namespace ecsact::entt { + +template +auto check_add_component_error( // + ::entt::registry&, + ::ecsact::entt::entity_id, + const C& +) -> ecsact_add_error { + static_assert(detail::error_check_unimplemented_by_codegen, R"( + ----------------------------------------------------------------------------- +| (!) CODEGEN ERROR | +| `check_add_component_error<>` template specialization cannot be found. This | +| is typically generated by ecsact_rt_entt_codegen. | + ----------------------------------------------------------------------------- +)"); +} + +template +auto check_update_component_error( // + ::entt::registry&, + ::ecsact::entt::entity_id, + const C& +) -> ecsact_update_error { + static_assert(detail::error_check_unimplemented_by_codegen, R"( + ----------------------------------------------------------------------------- +| (!) CODEGEN ERROR | +| `check_update_component_error<>` template specialization cannot be found. | +| This is typically generated by ecsact_rt_entt_codegen. | + ----------------------------------------------------------------------------- +)"); +} + +template +auto check_action_error( // + ::entt::registry&, + const A& +) -> ecsact_execute_systems_error { + static_assert(detail::error_check_unimplemented_by_codegen, R"( + ----------------------------------------------------------------------------- +| (!) CODEGEN ERROR | +| `check_action_error<>` template specialization cannot be found. | +| This is typically generated by ecsact_rt_entt_codegen. | + ----------------------------------------------------------------------------- +)"); +} + +} // namespace ecsact::entt diff --git a/ecsact/entt/registry_util.hh b/ecsact/entt/registry_util.hh index bb72897..7dea723 100644 --- a/ecsact/entt/registry_util.hh +++ b/ecsact/entt/registry_util.hh @@ -1,33 +1,33 @@ -#pragma once - -#include -#include "entt/entity/registry.hpp" -#include "ecsact/entt/detail/globals.hh" - -namespace ecsact::entt { - -inline auto get_registry( // - ecsact_registry_id id -) -> ::entt::registry& { - using ecsact::entt::detail::globals::registries; - - // Check to make sure we're not trying to get a registry that doesn't exist - // or has been destroyed. - assert(registries.contains(id)); - return registries.at(id); -} - -inline auto create_registry() - -> std::tuple { - using ecsact::entt::detail::globals::last_registry_id; - using ecsact::entt::detail::globals::registries; - - auto registry_id = static_cast( - ++reinterpret_cast(last_registry_id) - ); - auto& registry = registries[registry_id]; - - return {registry_id, std::ref(registry)}; -} - -} // namespace ecsact::entt +#pragma once + +#include +#include "entt/entity/registry.hpp" +#include "ecsact/entt/detail/globals.hh" + +namespace ecsact::entt { + +inline auto get_registry( // + ecsact_registry_id id +) -> ::entt::registry& { + using ecsact::entt::detail::globals::registries; + + // Check to make sure we're not trying to get a registry that doesn't exist + // or has been destroyed. + assert(registries.contains(id)); + return registries.at(id); +} + +inline auto create_registry() + -> std::tuple { + using ecsact::entt::detail::globals::last_registry_id; + using ecsact::entt::detail::globals::registries; + + auto registry_id = static_cast( + ++reinterpret_cast(last_registry_id) + ); + auto& registry = registries[registry_id]; + + return {registry_id, std::ref(registry)}; +} + +} // namespace ecsact::entt diff --git a/ecsact/entt/wrapper/core.hh b/ecsact/entt/wrapper/core.hh index 01ced54..e9836ea 100644 --- a/ecsact/entt/wrapper/core.hh +++ b/ecsact/entt/wrapper/core.hh @@ -1,392 +1,392 @@ -#pragma once - -#include -#include -#include "ecsact/runtime/common.h" -#include "ecsact/entt/detail/internal_markers.hh" -#include "ecsact/entt/event_markers.hh" -#include "entt/entity/registry.hpp" -#include "ecsact/entt/registry_util.hh" -#include "ecsact/entt/error_check.hh" -#include "ecsact/entt/detail/execution_events_collector.hh" - -namespace ecsact::entt::wrapper::core { - -template -inline auto has_component( // - ecsact_registry_id registry_id, - ecsact_entity_id entity_id, - [[maybe_unused]] ecsact_component_id component_id -) -> bool { - auto& reg = ecsact::entt::get_registry(registry_id); - auto entity = ecsact::entt::entity_id{entity_id}; - assert(C::id == component_id); - return reg.all_of(entity); -} - -template -inline auto get_component( - ecsact_registry_id registry_id, - ecsact_entity_id entity_id, - [[maybe_unused]] ecsact_component_id component_id -) -> const void* { - auto& reg = ecsact::entt::get_registry(registry_id); - auto entity = ecsact::entt::entity_id{entity_id}; - assert(C::id == component_id); - - const C& comp = reg.get(entity); - return ∁ -} - -template -inline auto add_component( // - ecsact_registry_id registry_id, - ecsact_entity_id entity_id, - [[maybe_unused]] ecsact_component_id component_id, - const void* component_data -) -> ecsact_add_error { - auto& reg = ecsact::entt::get_registry(registry_id); - auto entity = ecsact::entt::entity_id{entity_id}; - assert(C::id == component_id); - - auto err = ecsact::entt::check_add_component_error( - reg, - entity, - *static_cast(component_data) - ); - - if(err == ECSACT_ADD_OK) { - if constexpr(std::is_empty_v) { - reg.emplace(entity); - } else { - reg.emplace>( - entity, - *static_cast(component_data) - ); - reg.emplace(entity, *static_cast(component_data)); - } - } - - return err; -} - -template -inline auto add_component_exec_options( // - ecsact_registry_id registry_id, - ecsact_entity_id entity_id, - [[maybe_unused]] ecsact_component_id component_id, - const void* component_data -) -> ecsact_add_error { - auto& reg = ecsact::entt::get_registry(registry_id); - auto entity = ecsact::entt::entity_id{entity_id}; - assert(C::id == component_id); - - auto err = ecsact::entt::check_add_component_error( - reg, - entity, - *static_cast(component_data) - ); - - assert(err == ECSACT_ADD_OK); - - if(err == ECSACT_ADD_OK) { - if constexpr(std::is_empty_v) { - reg.emplace(entity); - } else { - reg.emplace>( - entity, - *static_cast(component_data) - ); - reg.emplace(entity, *static_cast(component_data)); - } - reg.template emplace_or_replace>(entity); - } - - return err; -} - -template -inline auto update_component( // - ecsact_registry_id registry_id, - ecsact_entity_id entity_id, - [[maybe_unused]] ecsact_component_id component_id, - const void* component_data -) -> ecsact_update_error { - auto& reg = ecsact::entt::get_registry(registry_id); - auto entity = ecsact::entt::entity_id{entity_id}; - assert(C::id == component_id); - static_assert(!std::is_empty_v, "Tag components cannot be updated"); - - auto err = ecsact::entt::check_update_component_error( - reg, - entity, - *static_cast(component_data) - ); - - if(err == ECSACT_UPDATE_OK) { - reg.replace(entity, *static_cast(component_data)); - } - - return err; -} - -template -inline auto update_component_exec_options( // - ecsact_registry_id registry_id, - ecsact_entity_id entity_id, - [[maybe_unused]] ecsact_component_id component_id, - const void* component_data -) -> ecsact_update_error { - auto& reg = ecsact::entt::get_registry(registry_id); - auto entity = ecsact::entt::entity_id{entity_id}; - assert(C::id == component_id); - static_assert(!std::is_empty_v, "Tag components cannot be updated"); - - auto err = ecsact::entt::check_update_component_error( - reg, - entity, - *static_cast(component_data) - ); - - if(err == ECSACT_UPDATE_OK) { - reg.replace(entity, *static_cast(component_data)); - reg.template emplace_or_replace>(entity); - } - - return err; -} - -template -auto remove_component( - ecsact_registry_id registry_id, - ecsact_entity_id entity_id, - [[maybe_unused]] ecsact_component_id component_id -) -> void { - auto& reg = ecsact::entt::get_registry(registry_id); - auto entity = ecsact::entt::entity_id{entity_id}; - assert(C::id == component_id); - - reg.remove(entity); - if constexpr(!std::is_empty_v) { - reg.remove>(entity); - } - reg.template remove>(entity); - reg.template remove>(entity); - reg.template emplace_or_replace>(entity); -} - -template -auto remove_component_exec_options( - ecsact_registry_id registry_id, - ecsact_entity_id entity_id, - [[maybe_unused]] ecsact_component_id component_id -) -> void { - using ecsact::entt::detail::pending_remove; - - auto& reg = ecsact::entt::get_registry(registry_id); - auto entity = ecsact::entt::entity_id{entity_id}; - assert(C::id == component_id); - - if constexpr(!std::is_empty_v) { - reg.template emplace_or_replace>( - entity, - reg.template get(entity) - ); - } - - reg.template erase(entity); - reg.template remove>(entity); - reg.template remove>(entity); - reg.template emplace_or_replace>(entity); - - if constexpr(!std::is_empty_v) { - reg.template remove>(entity); - } -} - -inline auto _trigger_create_entity_events( - ecsact_registry_id registry_id, - ecsact::entt::detail::execution_events_collector& events_collector -) -> void { - using ecsact::entt::detail::created_entity; - - auto& reg = ecsact::entt::get_registry(registry_id); - - ::entt::basic_view created_view{ - reg.template storage(), - }; - - for(ecsact::entt::entity_id entity : created_view) { - events_collector.invoke_entity_created_callback( - entity, - created_view.template get(entity).placeholder_entity_id - ); - } -} - -inline auto _trigger_destroy_entity_events( - ecsact_registry_id registry_id, - ecsact::entt::detail::execution_events_collector& events_collector -) -> void { - auto& reg = ecsact::entt::get_registry(registry_id); - - using ecsact::entt::detail::destroyed_entity; - - if(!events_collector.has_entity_destroyed_callback()) { - return; - } - - ::entt::basic_view destroy_view{ - reg.template storage(), - }; - - for(ecsact::entt::entity_id entity : destroy_view) { - events_collector.invoke_entity_destroyed_callback(entity); - } -} - -template -auto _trigger_init_component_event( - ecsact_registry_id registry_id, - ecsact::entt::detail::execution_events_collector& events_collector -) -> void { - auto& reg = ecsact::entt::get_registry(registry_id); - - if(!events_collector.has_init_callback()) { - return; - } - - if constexpr(C::transient) { - return; - } - - ::entt::basic_view added_view{ - reg.template storage(), - reg.template storage>(), - }; - - for(ecsact::entt::entity_id entity : added_view) { - if constexpr(std::is_empty_v) { - events_collector.invoke_init_callback(entity); - } else { - events_collector.invoke_init_callback( - entity, - added_view.template get(entity) - ); - } - } -} - -template -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::detail::beforechange_storage; - - if(!events_collector.has_update_callback()) { - return; - } - - auto& reg = ecsact::entt::get_registry(registry_id); - if constexpr(!C::transient && !std::is_empty_v) { - ::entt::basic_view changed_view{ - reg.template storage(), - reg.template storage>(), - reg.template storage>(), - }; - - for(ecsact::entt::entity_id entity : changed_view) { - auto& before = changed_view.template get>(entity); - auto& current = changed_view.template get(entity); - - if(before.value != current) { - events_collector.invoke_update_callback(entity, current); - } - } - } -} - -template -auto _trigger_remove_component_event( - ecsact_registry_id registry_id, - ecsact::entt::detail::execution_events_collector& events_collector -) -> void { - auto& reg = ecsact::entt::get_registry(registry_id); - - if(!events_collector.has_remove_callback()) { - return; - } - - if constexpr(C::transient) { - return; - } - - if constexpr(std::is_empty_v) { - ::entt::basic_view removed_view{ - reg.template storage>(), - }; - for(ecsact::entt::entity_id entity : removed_view) { - events_collector.invoke_remove_callback(entity); - } - } else { - ::entt::basic_view removed_view{ - reg.template storage>(), - reg.template storage>(), - }; - for(ecsact::entt::entity_id entity : removed_view) { - events_collector.invoke_remove_callback( - entity, - removed_view.template get>(entity).value - ); - } - - reg.template clear>(); - } -} - -auto check_action_error_t( - ecsact_registry_id registry_id, - const void* action_data -) -> ecsact_execute_systems_error; - -template -inline auto check_action_error( - ecsact_registry_id registry_id, - const void* action_data -) -> ecsact_execute_systems_error { - auto& reg = ecsact::entt::get_registry(registry_id); - - auto action = *static_cast(action_data); - auto result = ecsact::entt::check_action_error(reg, action); - - return result; -} - -template -inline auto clear_component(ecsact_registry_id registry_id) -> void { - auto& reg = ecsact::entt::get_registry(registry_id); - - reg.clear>(); - reg.clear>(); - reg.clear>(); -} - -template -inline auto prepare_component(ecsact_registry_id registry_id) -> void { - using namespace ecsact::entt; - - auto& reg = ecsact::entt::get_registry(registry_id); - - reg.template storage(); - reg.template storage>(); - reg.template storage>(); - - if constexpr(!std::is_empty_v) { - reg.storage>(); - reg.template storage>(); - } -} - -} // namespace ecsact::entt::wrapper::core +#pragma once + +#include +#include +#include "ecsact/runtime/common.h" +#include "ecsact/entt/detail/internal_markers.hh" +#include "ecsact/entt/event_markers.hh" +#include "entt/entity/registry.hpp" +#include "ecsact/entt/registry_util.hh" +#include "ecsact/entt/error_check.hh" +#include "ecsact/entt/detail/execution_events_collector.hh" + +namespace ecsact::entt::wrapper::core { + +template +inline auto has_component( // + ecsact_registry_id registry_id, + ecsact_entity_id entity_id, + [[maybe_unused]] ecsact_component_id component_id +) -> bool { + auto& reg = ecsact::entt::get_registry(registry_id); + auto entity = ecsact::entt::entity_id{entity_id}; + assert(C::id == component_id); + return reg.all_of(entity); +} + +template +inline auto get_component( + ecsact_registry_id registry_id, + ecsact_entity_id entity_id, + [[maybe_unused]] ecsact_component_id component_id +) -> const void* { + auto& reg = ecsact::entt::get_registry(registry_id); + auto entity = ecsact::entt::entity_id{entity_id}; + assert(C::id == component_id); + + const C& comp = reg.get(entity); + return ∁ +} + +template +inline auto add_component( // + ecsact_registry_id registry_id, + ecsact_entity_id entity_id, + [[maybe_unused]] ecsact_component_id component_id, + const void* component_data +) -> ecsact_add_error { + auto& reg = ecsact::entt::get_registry(registry_id); + auto entity = ecsact::entt::entity_id{entity_id}; + assert(C::id == component_id); + + auto err = ecsact::entt::check_add_component_error( + reg, + entity, + *static_cast(component_data) + ); + + if(err == ECSACT_ADD_OK) { + if constexpr(std::is_empty_v) { + reg.emplace(entity); + } else { + reg.emplace>( + entity, + *static_cast(component_data) + ); + reg.emplace(entity, *static_cast(component_data)); + } + } + + return err; +} + +template +inline auto add_component_exec_options( // + ecsact_registry_id registry_id, + ecsact_entity_id entity_id, + [[maybe_unused]] ecsact_component_id component_id, + const void* component_data +) -> ecsact_add_error { + auto& reg = ecsact::entt::get_registry(registry_id); + auto entity = ecsact::entt::entity_id{entity_id}; + assert(C::id == component_id); + + auto err = ecsact::entt::check_add_component_error( + reg, + entity, + *static_cast(component_data) + ); + + assert(err == ECSACT_ADD_OK); + + if(err == ECSACT_ADD_OK) { + if constexpr(std::is_empty_v) { + reg.emplace(entity); + } else { + reg.emplace>( + entity, + *static_cast(component_data) + ); + reg.emplace(entity, *static_cast(component_data)); + } + reg.template emplace_or_replace>(entity); + } + + return err; +} + +template +inline auto update_component( // + ecsact_registry_id registry_id, + ecsact_entity_id entity_id, + [[maybe_unused]] ecsact_component_id component_id, + const void* component_data +) -> ecsact_update_error { + auto& reg = ecsact::entt::get_registry(registry_id); + auto entity = ecsact::entt::entity_id{entity_id}; + assert(C::id == component_id); + static_assert(!std::is_empty_v, "Tag components cannot be updated"); + + auto err = ecsact::entt::check_update_component_error( + reg, + entity, + *static_cast(component_data) + ); + + if(err == ECSACT_UPDATE_OK) { + reg.replace(entity, *static_cast(component_data)); + } + + return err; +} + +template +inline auto update_component_exec_options( // + ecsact_registry_id registry_id, + ecsact_entity_id entity_id, + [[maybe_unused]] ecsact_component_id component_id, + const void* component_data +) -> ecsact_update_error { + auto& reg = ecsact::entt::get_registry(registry_id); + auto entity = ecsact::entt::entity_id{entity_id}; + assert(C::id == component_id); + static_assert(!std::is_empty_v, "Tag components cannot be updated"); + + auto err = ecsact::entt::check_update_component_error( + reg, + entity, + *static_cast(component_data) + ); + + if(err == ECSACT_UPDATE_OK) { + reg.replace(entity, *static_cast(component_data)); + reg.template emplace_or_replace>(entity); + } + + return err; +} + +template +auto remove_component( + ecsact_registry_id registry_id, + ecsact_entity_id entity_id, + [[maybe_unused]] ecsact_component_id component_id +) -> void { + auto& reg = ecsact::entt::get_registry(registry_id); + auto entity = ecsact::entt::entity_id{entity_id}; + assert(C::id == component_id); + + reg.remove(entity); + if constexpr(!std::is_empty_v) { + reg.remove>(entity); + } + reg.template remove>(entity); + reg.template remove>(entity); + reg.template emplace_or_replace>(entity); +} + +template +auto remove_component_exec_options( + ecsact_registry_id registry_id, + ecsact_entity_id entity_id, + [[maybe_unused]] ecsact_component_id component_id +) -> void { + using ecsact::entt::detail::pending_remove; + + auto& reg = ecsact::entt::get_registry(registry_id); + auto entity = ecsact::entt::entity_id{entity_id}; + assert(C::id == component_id); + + if constexpr(!std::is_empty_v) { + reg.template emplace_or_replace>( + entity, + reg.template get(entity) + ); + } + + reg.template erase(entity); + reg.template remove>(entity); + reg.template remove>(entity); + reg.template emplace_or_replace>(entity); + + if constexpr(!std::is_empty_v) { + reg.template remove>(entity); + } +} + +inline auto _trigger_create_entity_events( + ecsact_registry_id registry_id, + ecsact::entt::detail::execution_events_collector& events_collector +) -> void { + using ecsact::entt::detail::created_entity; + + auto& reg = ecsact::entt::get_registry(registry_id); + + ::entt::basic_view created_view{ + reg.template storage(), + }; + + for(ecsact::entt::entity_id entity : created_view) { + events_collector.invoke_entity_created_callback( + entity, + created_view.template get(entity).placeholder_entity_id + ); + } +} + +inline auto _trigger_destroy_entity_events( + ecsact_registry_id registry_id, + ecsact::entt::detail::execution_events_collector& events_collector +) -> void { + auto& reg = ecsact::entt::get_registry(registry_id); + + using ecsact::entt::detail::destroyed_entity; + + if(!events_collector.has_entity_destroyed_callback()) { + return; + } + + ::entt::basic_view destroy_view{ + reg.template storage(), + }; + + for(ecsact::entt::entity_id entity : destroy_view) { + events_collector.invoke_entity_destroyed_callback(entity); + } +} + +template +auto _trigger_init_component_event( + ecsact_registry_id registry_id, + ecsact::entt::detail::execution_events_collector& events_collector +) -> void { + auto& reg = ecsact::entt::get_registry(registry_id); + + if(!events_collector.has_init_callback()) { + return; + } + + if constexpr(C::transient) { + return; + } + + ::entt::basic_view added_view{ + reg.template storage(), + reg.template storage>(), + }; + + for(ecsact::entt::entity_id entity : added_view) { + if constexpr(std::is_empty_v) { + events_collector.invoke_init_callback(entity); + } else { + events_collector.invoke_init_callback( + entity, + added_view.template get(entity) + ); + } + } +} + +template +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::detail::beforechange_storage; + + if(!events_collector.has_update_callback()) { + return; + } + + auto& reg = ecsact::entt::get_registry(registry_id); + if constexpr(!C::transient && !std::is_empty_v) { + ::entt::basic_view changed_view{ + reg.template storage(), + reg.template storage>(), + reg.template storage>(), + }; + + for(ecsact::entt::entity_id entity : changed_view) { + auto& before = changed_view.template get>(entity); + auto& current = changed_view.template get(entity); + + if(before.value != current) { + events_collector.invoke_update_callback(entity, current); + } + } + } +} + +template +auto _trigger_remove_component_event( + ecsact_registry_id registry_id, + ecsact::entt::detail::execution_events_collector& events_collector +) -> void { + auto& reg = ecsact::entt::get_registry(registry_id); + + if(!events_collector.has_remove_callback()) { + return; + } + + if constexpr(C::transient) { + return; + } + + if constexpr(std::is_empty_v) { + ::entt::basic_view removed_view{ + reg.template storage>(), + }; + for(ecsact::entt::entity_id entity : removed_view) { + events_collector.invoke_remove_callback(entity); + } + } else { + ::entt::basic_view removed_view{ + reg.template storage>(), + reg.template storage>(), + }; + for(ecsact::entt::entity_id entity : removed_view) { + events_collector.invoke_remove_callback( + entity, + removed_view.template get>(entity).value + ); + } + + reg.template clear>(); + } +} + +auto check_action_error_t( + ecsact_registry_id registry_id, + const void* action_data +) -> ecsact_execute_systems_error; + +template +inline auto check_action_error( + ecsact_registry_id registry_id, + const void* action_data +) -> ecsact_execute_systems_error { + auto& reg = ecsact::entt::get_registry(registry_id); + + auto action = *static_cast(action_data); + auto result = ecsact::entt::check_action_error(reg, action); + + return result; +} + +template +inline auto clear_component(ecsact_registry_id registry_id) -> void { + auto& reg = ecsact::entt::get_registry(registry_id); + + reg.clear>(); + reg.clear>(); + reg.clear>(); +} + +template +inline auto prepare_component(ecsact_registry_id registry_id) -> void { + using namespace ecsact::entt; + + auto& reg = ecsact::entt::get_registry(registry_id); + + reg.template storage(); + reg.template storage>(); + reg.template storage>(); + + if constexpr(!std::is_empty_v) { + reg.storage>(); + reg.template storage>(); + } +} + +} // namespace ecsact::entt::wrapper::core diff --git a/rt_entt_codegen/BUILD.bazel b/rt_entt_codegen/BUILD.bazel index 8288c0e..2219a05 100644 --- a/rt_entt_codegen/BUILD.bazel +++ b/rt_entt_codegen/BUILD.bazel @@ -1,22 +1,22 @@ -load("@ecsact_lang_cpp//:codegen_plugin.bzl", "cc_ecsact_codegen_plugin") -load("//bazel:copts.bzl", "copts") - -package(default_visibility = ["//visibility:public"]) - -cc_ecsact_codegen_plugin( - name = "ecsact_rt_entt_codegen", - srcs = ["rt_entt_codegen.cc"], - copts = copts, - output_extension = "rt_entt.cc", - deps = [ - "//rt_entt_codegen/core", - "//rt_entt_codegen/shared:ecsact_entt_details", - "//rt_entt_codegen/shared:util", - "@ecsact_lang_cpp//:support", - ], -) - -alias( - name = "rt_entt_codegen", - actual = ":ecsact_rt_entt_codegen", -) +load("@ecsact_lang_cpp//:codegen_plugin.bzl", "cc_ecsact_codegen_plugin") +load("//bazel:copts.bzl", "copts") + +package(default_visibility = ["//visibility:public"]) + +cc_ecsact_codegen_plugin( + name = "ecsact_rt_entt_codegen", + srcs = ["rt_entt_codegen.cc"], + copts = copts, + output_extension = "rt_entt.cc", + deps = [ + "//rt_entt_codegen/core", + "//rt_entt_codegen/shared:ecsact_entt_details", + "//rt_entt_codegen/shared:util", + "@ecsact_lang_cpp//:support", + ], +) + +alias( + name = "rt_entt_codegen", + actual = ":ecsact_rt_entt_codegen", +) diff --git a/rt_entt_codegen/core/BUILD.bazel b/rt_entt_codegen/core/BUILD.bazel index 423c99a..c02a5f6 100644 --- a/rt_entt_codegen/core/BUILD.bazel +++ b/rt_entt_codegen/core/BUILD.bazel @@ -1,47 +1,47 @@ -load("@rules_cc//cc:defs.bzl", "cc_library") -load("//bazel:copts.bzl", "copts") - -cc_library( - name = "core_internal", - hdrs = ["core.hh"], - copts = copts, - visibility = ["//rt_entt_codegen:__pkg__"], - deps = ["//rt_entt_codegen/shared:ecsact_entt_details"], -) - -# keep sorted -_CORE_CODEGEN_METHODS = { - "execute_systems": [], - "create_registry": [], - "init_registry_storage": [], - "events": [], - "print_sys_exec": [ - "//rt_entt_codegen/shared:comps_with_caps", - "@entt//:entt", - "@ecsact_rt_entt//:lib", - ], - "check_error_template_specializations": [], - "execution_options": [], -} - -[cc_library( - name = method, - srcs = ["{}.cc".format(method)], - copts = copts, - defines = ["ECSACT_META_API_LOAD_AT_RUNTIME"], - deps = _CORE_CODEGEN_METHODS[method] + [ - ":core_internal", - "//rt_entt_codegen/shared:util", - "@ecsact_codegen//:plugin", - "@ecsact_lang_cpp//:cpp_codegen_plugin_util", - "@ecsact_lang_cpp//:support", - "@ecsact_runtime//:meta", - ], -) for method in _CORE_CODEGEN_METHODS] - -cc_library( - name = "core", - copts = copts, - visibility = ["//rt_entt_codegen:__pkg__"], - deps = [":core_internal"] + [":{}".format(method) for method in _CORE_CODEGEN_METHODS], -) +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//bazel:copts.bzl", "copts") + +cc_library( + name = "core_internal", + hdrs = ["core.hh"], + copts = copts, + visibility = ["//rt_entt_codegen:__pkg__"], + deps = ["//rt_entt_codegen/shared:ecsact_entt_details"], +) + +# keep sorted +_CORE_CODEGEN_METHODS = { + "execute_systems": [], + "create_registry": [], + "init_registry_storage": [], + "events": [], + "print_sys_exec": [ + "//rt_entt_codegen/shared:comps_with_caps", + "@entt//:entt", + "@ecsact_rt_entt//:lib", + ], + "check_error_template_specializations": [], + "execution_options": [], +} + +[cc_library( + name = method, + srcs = ["{}.cc".format(method)], + copts = copts, + defines = ["ECSACT_META_API_LOAD_AT_RUNTIME"], + deps = _CORE_CODEGEN_METHODS[method] + [ + ":core_internal", + "//rt_entt_codegen/shared:util", + "@ecsact_codegen//:plugin", + "@ecsact_lang_cpp//:cpp_codegen_plugin_util", + "@ecsact_lang_cpp//:support", + "@ecsact_runtime//:meta", + ], +) for method in _CORE_CODEGEN_METHODS] + +cc_library( + name = "core", + copts = copts, + visibility = ["//rt_entt_codegen:__pkg__"], + deps = [":core_internal"] + [":{}".format(method) for method in _CORE_CODEGEN_METHODS], +) diff --git a/rt_entt_codegen/core/check_error_template_specializations.cc b/rt_entt_codegen/core/check_error_template_specializations.cc index bf22d68..79c5ae1 100644 --- a/rt_entt_codegen/core/check_error_template_specializations.cc +++ b/rt_entt_codegen/core/check_error_template_specializations.cc @@ -1,157 +1,157 @@ -#include "core.hh" - -#include -#include "ecsact/runtime/meta.hh" -#include "ecsact/lang-support/lang-cc.hh" -#include "ecsact/cpp_codegen_plugin_util.hh" -#include "rt_entt_codegen/shared/util.hh" - -template -static auto for_each_entity_field(CompositeID composite_id, Fn&& fn) { - for(auto field_id : ecsact::meta::get_field_ids(composite_id)) { - auto field_type = ecsact_meta_field_type( - ecsact_id_cast(composite_id), - field_id - ); - - const auto is_entity_field = // - field_type.kind == ECSACT_TYPE_KIND_BUILTIN && - field_type.type.builtin == ECSACT_ENTITY_TYPE; - - if(!is_entity_field) { - continue; - } - - auto entity_field_name = std::string{ecsact_meta_field_name( - ecsact_id_cast(composite_id), - field_id - )}; - - fn(entity_field_name); - } -} - -static auto print_check_add_component_error_template_specialization( - ecsact::codegen_plugin_context& ctx, - const ecsact::rt_entt_codegen::ecsact_entt_details& details, - ecsact_component_id component_id -) -> void { - using ecsact::cpp_codegen_plugin_util::block; - using ecsact::cpp_codegen_plugin_util::method_printer; - using ecsact::rt_entt_codegen::util::decl_cpp_ident; - - auto cpp_component_ident = decl_cpp_ident(component_id); - - const auto method_name = - "ecsact::entt::check_add_component_error<" + cpp_component_ident + ">"; - - ctx.write("template<>\n"); - - auto printer = // - method_printer{ctx, method_name} - .parameter("::entt::registry&", "registry") - .parameter("::ecsact::entt::entity_id", "entity") - .parameter(cpp_component_ident + " const&", "component") - .return_type("ecsact_add_error"); - - for_each_entity_field(component_id, [&](auto field_name) { - auto field_var = "ecsact::entt::entity_id{component." + field_name + "}"; - block(ctx, "if(!registry.valid(" + field_var + "))", [&] { - ctx.write("return ECSACT_ADD_ERR_ENTITY_INVALID;\n"); - }); - }); - - ctx.write("return ECSACT_ADD_OK;"); -} - -static auto print_check_update_component_error_template_specialization( - ecsact::codegen_plugin_context& ctx, - const ecsact::rt_entt_codegen::ecsact_entt_details& details, - ecsact_component_id component_id -) -> void { - using ecsact::cpp_codegen_plugin_util::block; - using ecsact::cpp_codegen_plugin_util::method_printer; - using ecsact::rt_entt_codegen::util::decl_cpp_ident; - - auto cpp_component_ident = decl_cpp_ident(component_id); - - const auto method_name = - "ecsact::entt::check_update_component_error<" + cpp_component_ident + ">"; - - ctx.write("template<>\n"); - - auto printer = // - method_printer{ctx, method_name} - .parameter("::entt::registry&", "registry") - .parameter("::ecsact::entt::entity_id", "entity") - .parameter(cpp_component_ident + " const&", "component") - .return_type("ecsact_update_error"); - - for_each_entity_field(component_id, [&](auto field_name) { - auto field_var = "ecsact::entt::entity_id{component." + field_name + "}"; - block(ctx, "if(!registry.valid(" + field_var + "))", [&] { - ctx.write("return ECSACT_UPDATE_ERR_ENTITY_INVALID;\n"); - }); - }); - - ctx.write("return ECSACT_UPDATE_OK;"); -} - -static auto print_check_action_error_template_specialization( - ecsact::codegen_plugin_context& ctx, - const ecsact::rt_entt_codegen::ecsact_entt_details& details, - ecsact_action_id action_id -) -> void { - using ecsact::cpp_codegen_plugin_util::block; - using ecsact::cpp_codegen_plugin_util::method_printer; - using ecsact::rt_entt_codegen::util::decl_cpp_ident; - - auto cpp_action_ident = decl_cpp_ident(action_id); - - const auto method_name = - "ecsact::entt::check_action_error<" + cpp_action_ident + ">"; - - ctx.write("template<>\n"); - - auto printer = // - method_printer{ctx, method_name} - .parameter("::entt::registry&", "registry") - .parameter(cpp_action_ident + " const&", "action") - .return_type("ecsact_execute_systems_error"); - - ctx.write("auto err = ECSACT_EXEC_SYS_OK;\n"); - - for_each_entity_field(action_id, [&](auto field_name) { - auto field_var = "ecsact::entt::entity_id{action." + field_name + "}"; - block(ctx, "if(!registry.valid(" + field_var + "))", [&] { - ctx.write("return ECSACT_EXEC_SYS_ERR_ACTION_ENTITY_INVALID;\n"); - }); - }); - - ctx.write("return err;\n"); -} - -auto ecsact::rt_entt_codegen::core::print_check_error_template_specializations( - codegen_plugin_context& ctx, - const ecsact_entt_details& details -) -> void { - for(auto comp_id : details.all_components) { - print_check_add_component_error_template_specialization( - ctx, - details, - comp_id - ); - } - - for(auto comp_id : details.all_components) { - print_check_update_component_error_template_specialization( - ctx, - details, - comp_id - ); - } - - for(auto action_id : details.all_actions) { - print_check_action_error_template_specialization(ctx, details, action_id); - } -} +#include "core.hh" + +#include +#include "ecsact/runtime/meta.hh" +#include "ecsact/lang-support/lang-cc.hh" +#include "ecsact/cpp_codegen_plugin_util.hh" +#include "rt_entt_codegen/shared/util.hh" + +template +static auto for_each_entity_field(CompositeID composite_id, Fn&& fn) { + for(auto field_id : ecsact::meta::get_field_ids(composite_id)) { + auto field_type = ecsact_meta_field_type( + ecsact_id_cast(composite_id), + field_id + ); + + const auto is_entity_field = // + field_type.kind == ECSACT_TYPE_KIND_BUILTIN && + field_type.type.builtin == ECSACT_ENTITY_TYPE; + + if(!is_entity_field) { + continue; + } + + auto entity_field_name = std::string{ecsact_meta_field_name( + ecsact_id_cast(composite_id), + field_id + )}; + + fn(entity_field_name); + } +} + +static auto print_check_add_component_error_template_specialization( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::ecsact_entt_details& details, + ecsact_component_id component_id +) -> void { + using ecsact::cpp_codegen_plugin_util::block; + using ecsact::cpp_codegen_plugin_util::method_printer; + using ecsact::rt_entt_codegen::util::decl_cpp_ident; + + auto cpp_component_ident = decl_cpp_ident(component_id); + + const auto method_name = + "ecsact::entt::check_add_component_error<" + cpp_component_ident + ">"; + + ctx.write("template<>\n"); + + auto printer = // + method_printer{ctx, method_name} + .parameter("::entt::registry&", "registry") + .parameter("::ecsact::entt::entity_id", "entity") + .parameter(cpp_component_ident + " const&", "component") + .return_type("ecsact_add_error"); + + for_each_entity_field(component_id, [&](auto field_name) { + auto field_var = "ecsact::entt::entity_id{component." + field_name + "}"; + block(ctx, "if(!registry.valid(" + field_var + "))", [&] { + ctx.write("return ECSACT_ADD_ERR_ENTITY_INVALID;\n"); + }); + }); + + ctx.write("return ECSACT_ADD_OK;"); +} + +static auto print_check_update_component_error_template_specialization( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::ecsact_entt_details& details, + ecsact_component_id component_id +) -> void { + using ecsact::cpp_codegen_plugin_util::block; + using ecsact::cpp_codegen_plugin_util::method_printer; + using ecsact::rt_entt_codegen::util::decl_cpp_ident; + + auto cpp_component_ident = decl_cpp_ident(component_id); + + const auto method_name = + "ecsact::entt::check_update_component_error<" + cpp_component_ident + ">"; + + ctx.write("template<>\n"); + + auto printer = // + method_printer{ctx, method_name} + .parameter("::entt::registry&", "registry") + .parameter("::ecsact::entt::entity_id", "entity") + .parameter(cpp_component_ident + " const&", "component") + .return_type("ecsact_update_error"); + + for_each_entity_field(component_id, [&](auto field_name) { + auto field_var = "ecsact::entt::entity_id{component." + field_name + "}"; + block(ctx, "if(!registry.valid(" + field_var + "))", [&] { + ctx.write("return ECSACT_UPDATE_ERR_ENTITY_INVALID;\n"); + }); + }); + + ctx.write("return ECSACT_UPDATE_OK;"); +} + +static auto print_check_action_error_template_specialization( + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::ecsact_entt_details& details, + ecsact_action_id action_id +) -> void { + using ecsact::cpp_codegen_plugin_util::block; + using ecsact::cpp_codegen_plugin_util::method_printer; + using ecsact::rt_entt_codegen::util::decl_cpp_ident; + + auto cpp_action_ident = decl_cpp_ident(action_id); + + const auto method_name = + "ecsact::entt::check_action_error<" + cpp_action_ident + ">"; + + ctx.write("template<>\n"); + + auto printer = // + method_printer{ctx, method_name} + .parameter("::entt::registry&", "registry") + .parameter(cpp_action_ident + " const&", "action") + .return_type("ecsact_execute_systems_error"); + + ctx.write("auto err = ECSACT_EXEC_SYS_OK;\n"); + + for_each_entity_field(action_id, [&](auto field_name) { + auto field_var = "ecsact::entt::entity_id{action." + field_name + "}"; + block(ctx, "if(!registry.valid(" + field_var + "))", [&] { + ctx.write("return ECSACT_EXEC_SYS_ERR_ACTION_ENTITY_INVALID;\n"); + }); + }); + + ctx.write("return err;\n"); +} + +auto ecsact::rt_entt_codegen::core::print_check_error_template_specializations( + codegen_plugin_context& ctx, + const ecsact_entt_details& details +) -> void { + for(auto comp_id : details.all_components) { + print_check_add_component_error_template_specialization( + ctx, + details, + comp_id + ); + } + + for(auto comp_id : details.all_components) { + print_check_update_component_error_template_specialization( + ctx, + details, + comp_id + ); + } + + for(auto action_id : details.all_actions) { + print_check_action_error_template_specialization(ctx, details, action_id); + } +} diff --git a/rt_entt_codegen/core/core.hh b/rt_entt_codegen/core/core.hh index 82c5d61..2d64a0d 100644 --- a/rt_entt_codegen/core/core.hh +++ b/rt_entt_codegen/core/core.hh @@ -1,54 +1,54 @@ -#pragma once - -#include "ecsact/runtime/meta.hh" -#include "ecsact/codegen/plugin.hh" -#include "rt_entt_codegen/shared/ecsact_entt_details.hh" - -namespace ecsact::rt_entt_codegen::core { - -auto print_execute_systems( // - codegen_plugin_context& ctx, - const ecsact_entt_details& details -) -> void; - -auto print_execution_options( // - codegen_plugin_context& ctx, - const ecsact_entt_details& details -) -> void; - -auto print_create_registry( // - codegen_plugin_context& ctx, - const ecsact_entt_details& details -) -> void; - -auto print_init_registry_storage( // - ecsact::codegen_plugin_context& ctx, - const ecsact::rt_entt_codegen::ecsact_entt_details& details -) -> void; - -auto print_execute_system_like_template_specializations( // - codegen_plugin_context& ctx, - const ecsact_entt_details& details -) -> void; - -auto print_check_error_template_specializations( // - codegen_plugin_context& ctx, - const ecsact_entt_details& details -) -> void; - -auto print_trigger_ecsact_events_minimal( // - codegen_plugin_context& ctx, - const ecsact_entt_details& details -) -> void; - -auto print_trigger_ecsact_events_all( // - codegen_plugin_context& ctx, - const ecsact_entt_details& details -) -> void; - -auto print_cleanup_ecsact_component_events( // - codegen_plugin_context& ctx, - const ecsact_entt_details& details -) -> void; - -} // namespace ecsact::rt_entt_codegen::core +#pragma once + +#include "ecsact/runtime/meta.hh" +#include "ecsact/codegen/plugin.hh" +#include "rt_entt_codegen/shared/ecsact_entt_details.hh" + +namespace ecsact::rt_entt_codegen::core { + +auto print_execute_systems( // + codegen_plugin_context& ctx, + const ecsact_entt_details& details +) -> void; + +auto print_execution_options( // + codegen_plugin_context& ctx, + const ecsact_entt_details& details +) -> void; + +auto print_create_registry( // + codegen_plugin_context& ctx, + const ecsact_entt_details& details +) -> void; + +auto print_init_registry_storage( // + ecsact::codegen_plugin_context& ctx, + const ecsact::rt_entt_codegen::ecsact_entt_details& details +) -> void; + +auto print_execute_system_like_template_specializations( // + codegen_plugin_context& ctx, + const ecsact_entt_details& details +) -> void; + +auto print_check_error_template_specializations( // + codegen_plugin_context& ctx, + const ecsact_entt_details& details +) -> void; + +auto print_trigger_ecsact_events_minimal( // + codegen_plugin_context& ctx, + const ecsact_entt_details& details +) -> void; + +auto print_trigger_ecsact_events_all( // + codegen_plugin_context& ctx, + const ecsact_entt_details& details +) -> void; + +auto print_cleanup_ecsact_component_events( // + codegen_plugin_context& ctx, + const ecsact_entt_details& details +) -> void; + +} // namespace ecsact::rt_entt_codegen::core diff --git a/rt_entt_codegen/core/create_registry.cc b/rt_entt_codegen/core/create_registry.cc index efc9849..03ba9fe 100644 --- a/rt_entt_codegen/core/create_registry.cc +++ b/rt_entt_codegen/core/create_registry.cc @@ -1,33 +1,33 @@ -#include "core.hh" - -#include "ecsact/lang-support/lang-cc.hh" -#include "rt_entt_codegen/shared/util.hh" - -auto ecsact::rt_entt_codegen::core::print_create_registry( // - codegen_plugin_context& ctx, - const ecsact_entt_details& details -) -> void { - using ecsact::cc_lang_support::cpp_identifier; - using ecsact::rt_entt_codegen::util::method_printer; - - auto printer = // - method_printer{ctx, "ecsact_create_registry"} - .parameter("const char*", "registry_name") - .return_type("ecsact_registry_id"); - - ctx.write("auto&& [registry_id, reg] = ecsact::entt::create_registry();\n\n"); - - if(!details.group_systems.empty()) { - ctx.write( - "// These groups were automatically selected based on the input ecsact " - "files\n" - ); - for(auto sys_id : details.group_systems) { - auto decl_name = ecsact::meta::decl_full_name(sys_id); - } - } - - ctx.write("ecsact_init_registry_storage(registry_id);\n"); - - ctx.write("\nreturn registry_id;"); -} +#include "core.hh" + +#include "ecsact/lang-support/lang-cc.hh" +#include "rt_entt_codegen/shared/util.hh" + +auto ecsact::rt_entt_codegen::core::print_create_registry( // + codegen_plugin_context& ctx, + const ecsact_entt_details& details +) -> void { + using ecsact::cc_lang_support::cpp_identifier; + using ecsact::rt_entt_codegen::util::method_printer; + + auto printer = // + method_printer{ctx, "ecsact_create_registry"} + .parameter("const char*", "registry_name") + .return_type("ecsact_registry_id"); + + ctx.write("auto&& [registry_id, reg] = ecsact::entt::create_registry();\n\n"); + + if(!details.group_systems.empty()) { + ctx.write( + "// These groups were automatically selected based on the input ecsact " + "files\n" + ); + for(auto sys_id : details.group_systems) { + auto decl_name = ecsact::meta::decl_full_name(sys_id); + } + } + + ctx.write("ecsact_init_registry_storage(registry_id);\n"); + + ctx.write("\nreturn registry_id;"); +} diff --git a/rt_entt_codegen/core/execute_systems.cc b/rt_entt_codegen/core/execute_systems.cc index 1956ce9..fd12404 100644 --- a/rt_entt_codegen/core/execute_systems.cc +++ b/rt_entt_codegen/core/execute_systems.cc @@ -1,95 +1,95 @@ -#include "core.hh" - -#include "ecsact/lang-support/lang-cc.hh" -#include "rt_entt_codegen/shared/util.hh" -#include "ecsact/cpp_codegen_plugin_util.hh" - -constexpr auto METHOD_BODY_TOP = R"( -auto& reg = ecsact::entt::get_registry(registry_id); -auto actions = ecsact::entt::actions_map{}; -)"; - -auto ecsact::rt_entt_codegen::core::print_execute_systems( // - 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::rt_entt_codegen::util::method_printer; - - auto printer = // - method_printer{ctx, "ecsact_execute_systems"} - .parameter("ecsact_registry_id", "registry_id") - .parameter("int", "execution_count") - .parameter("const ecsact_execution_options*", "execution_options_list") - .parameter("const ecsact_execution_events_collector*", "evc") - .return_type("ecsact_execute_systems_error"); - - ctx.write(METHOD_BODY_TOP); - - ctx.write("\n"); - - ctx.write("for(auto i=0; execution_count > i; ++i) {"); - ctx.indentation += 1; - ctx.write("\n"); - - ctx.write("actions.collect(i, execution_count, execution_options_list);\n"); - - block(ctx, "if(execution_options_list != nullptr)", [&] { - ctx.write( - "auto err = handle_execution_options(registry_id, " - "execution_options_list[i]);\n\n" - ); - block(ctx, "if(err != ECSACT_EXEC_SYS_OK)", [&] { - ctx.write("return err;"); - }); - }); - - for(auto sys_like : details.top_execution_order) { - auto cpp_decl_name = cpp_identifier(ecsact::meta::decl_full_name(sys_like)); - - if(details.is_action(sys_like)) { - ctx.write( - "ecsact::entt::execute_actions<", - cpp_decl_name, - ">(reg, actions.as_action_span<", - cpp_decl_name, - ">());\n" - ); - } else if(details.is_system(sys_like)) { - ctx.write( - "ecsact::entt::execute_system<", - cpp_decl_name, - ">(reg, nullptr);\n" - ); - } else { - ctx.write("// ??? unhandled ??? ", cpp_decl_name, "\n"); - } - } - - ctx.indentation -= 1; - ctx.write("\n}\n\n"); - - block(ctx, "if(evc != nullptr)", [&] { - ctx.write( - "auto events_collector = " - "ecsact::entt::detail::execution_events_collector{};\n" - ); - ctx.write("events_collector.target = evc;\n\n"); - - block(ctx, "if(execution_options_list == nullptr)", [&] { - ctx.write( - "trigger_component_events_minimal(registry_id, events_collector);\n\n" - ); - }); - - block(ctx, "else", [&] { - ctx.write( - "trigger_component_events_all(registry_id, events_collector);\n\n" - ); - }); - ctx.write("cleanup_component_events(registry_id);\n"); - }); - - ctx.write("return ECSACT_EXEC_SYS_OK;"); -} +#include "core.hh" + +#include "ecsact/lang-support/lang-cc.hh" +#include "rt_entt_codegen/shared/util.hh" +#include "ecsact/cpp_codegen_plugin_util.hh" + +constexpr auto METHOD_BODY_TOP = R"( +auto& reg = ecsact::entt::get_registry(registry_id); +auto actions = ecsact::entt::actions_map{}; +)"; + +auto ecsact::rt_entt_codegen::core::print_execute_systems( // + 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::rt_entt_codegen::util::method_printer; + + auto printer = // + method_printer{ctx, "ecsact_execute_systems"} + .parameter("ecsact_registry_id", "registry_id") + .parameter("int", "execution_count") + .parameter("const ecsact_execution_options*", "execution_options_list") + .parameter("const ecsact_execution_events_collector*", "evc") + .return_type("ecsact_execute_systems_error"); + + ctx.write(METHOD_BODY_TOP); + + ctx.write("\n"); + + ctx.write("for(auto i=0; execution_count > i; ++i) {"); + ctx.indentation += 1; + ctx.write("\n"); + + ctx.write("actions.collect(i, execution_count, execution_options_list);\n"); + + block(ctx, "if(execution_options_list != nullptr)", [&] { + ctx.write( + "auto err = handle_execution_options(registry_id, " + "execution_options_list[i]);\n\n" + ); + block(ctx, "if(err != ECSACT_EXEC_SYS_OK)", [&] { + ctx.write("return err;"); + }); + }); + + for(auto sys_like : details.top_execution_order) { + auto cpp_decl_name = cpp_identifier(ecsact::meta::decl_full_name(sys_like)); + + if(details.is_action(sys_like)) { + ctx.write( + "ecsact::entt::execute_actions<", + cpp_decl_name, + ">(reg, actions.as_action_span<", + cpp_decl_name, + ">());\n" + ); + } else if(details.is_system(sys_like)) { + ctx.write( + "ecsact::entt::execute_system<", + cpp_decl_name, + ">(reg, nullptr);\n" + ); + } else { + ctx.write("// ??? unhandled ??? ", cpp_decl_name, "\n"); + } + } + + ctx.indentation -= 1; + ctx.write("\n}\n\n"); + + block(ctx, "if(evc != nullptr)", [&] { + ctx.write( + "auto events_collector = " + "ecsact::entt::detail::execution_events_collector{};\n" + ); + ctx.write("events_collector.target = evc;\n\n"); + + block(ctx, "if(execution_options_list == nullptr)", [&] { + ctx.write( + "trigger_component_events_minimal(registry_id, events_collector);\n\n" + ); + }); + + block(ctx, "else", [&] { + ctx.write( + "trigger_component_events_all(registry_id, events_collector);\n\n" + ); + }); + ctx.write("cleanup_component_events(registry_id);\n"); + }); + + ctx.write("return ECSACT_EXEC_SYS_OK;"); +} diff --git a/rt_entt_codegen/rt_entt_codegen.cc b/rt_entt_codegen/rt_entt_codegen.cc index 9da23f0..1546645 100644 --- a/rt_entt_codegen/rt_entt_codegen.cc +++ b/rt_entt_codegen/rt_entt_codegen.cc @@ -1,215 +1,215 @@ -#include -#include -#include -#include "core/core.hh" -#include "ecsact/runtime/meta.hh" -#include "ecsact/codegen/plugin.h" -#include "ecsact/codegen/plugin.hh" -#include "ecsact/lang-support/lang-cc.hh" - -#include "rt_entt_codegen/core/core.hh" -#include "rt_entt_codegen/shared/ecsact_entt_details.hh" -#include "shared/util.hh" - -constexpr auto GENERATED_FILE_DISCLAIMER = R"( -// GENERATED FILE - DO NOT EDIT -)"; - -constexpr auto MAIN_PACKAGE_ONLY_DISCLAIMER = R"( -// Purposely empty. ecsact_rt_entt_codegen is only for the 'main' package -)"; - -void ecsact_codegen_plugin( - ecsact_package_id package_id, - ecsact_codegen_write_fn_t write_fn -) { - using ecsact::cc_lang_support::c_identifier; - using ecsact::cc_lang_support::cpp_identifier; - using ecsact::meta::decl_full_name; - using ecsact::meta::get_all_system_like_ids; - using ecsact::rt_entt_codegen::ecsact_entt_details; - using ecsact::rt_entt_codegen::util::global_initializer_printer; - using ecsact::rt_entt_codegen::util::inc_header; - using ecsact::rt_entt_codegen::util::inc_package_header; - using ecsact::rt_entt_codegen::util::init_global; - - ecsact::codegen_plugin_context ctx{package_id, write_fn}; - - ctx.write(GENERATED_FILE_DISCLAIMER); - - if(ecsact_meta_main_package() != package_id) { - ctx.write(MAIN_PACKAGE_ONLY_DISCLAIMER); - return; - } - - auto details = ecsact_entt_details::from_package(package_id); - - inc_header(ctx, "ecsact/entt/entity.hh"); - inc_header(ctx, "ecsact/entt/event_markers.hh"); - inc_header(ctx, "ecsact/entt/execution.hh"); - 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/wrapper/core.hh"); - inc_header(ctx, "ecsact/entt/wrapper/dynamic.hh"); - inc_header(ctx, "ecsact/entt/error_check.hh"); - ctx.write("\n"); - inc_package_header(ctx, package_id); - for(auto dep : ecsact::meta::get_dependencies(package_id)) { - inc_package_header(ctx, dep); - } - ctx.write("\n"); - - init_global(ctx, "registries"); - init_global(ctx, "last_registry_id"); - init_global(ctx, "system_impls"); - - init_global(ctx, "all_component_ids", [&] { - if(details.all_components.empty()) { - return; - } - - ctx.write("result.reserve(", details.all_components.size(), ");\n"); - - for(auto comp_id : details.all_components) { - auto cpp_comp_name = cpp_identifier(decl_full_name(comp_id)); - ctx.write("result.insert(", cpp_comp_name, "::id);\n"); - } - }); - - init_global(ctx, "add_component_fns", [&] { - if(details.all_components.empty()) { - return; - } - - ctx.write("result.reserve(", details.all_components.size(), ");\n"); - - for(auto comp_id : details.all_components) { - auto cpp_comp_name = cpp_identifier(decl_full_name(comp_id)); - ctx.write( - "result.insert({::", - cpp_comp_name, - "::id, ", - "&ecsact::entt::wrapper::core::add_component<::", - cpp_comp_name, - ">});\n" - ); - } - }); - - init_global(ctx, "get_component_fns", [&] { - if(details.all_components.empty()) { - return; - } - - auto non_tag_component_ids = - details.all_components | - std::views::filter([&](ecsact_component_id comp_id) -> bool { - return !ecsact::meta::get_field_ids(comp_id).empty(); - }); - - ctx.write( - "result.reserve(", - std::ranges::distance(non_tag_component_ids), - ");\n" - ); - - for(auto comp_id : non_tag_component_ids) { - auto cpp_comp_name = cpp_identifier(decl_full_name(comp_id)); - ctx.write( - "result.insert({::", - cpp_comp_name, - "::id, ", - "&ecsact::entt::wrapper::core::get_component<::", - cpp_comp_name, - ">});\n" - ); - } - }); - - init_global(ctx, "update_component_fns", [&] { - if(details.all_components.empty()) { - return; - } - - auto non_tag_component_ids = - details.all_components | - std::views::filter([&](ecsact_component_id comp_id) -> bool { - return !ecsact::meta::get_field_ids(comp_id).empty(); - }); - - ctx.write( - "result.reserve(", - std::ranges::distance(non_tag_component_ids), - ");\n" - ); - - for(auto comp_id : non_tag_component_ids) { - auto cpp_comp_name = cpp_identifier(decl_full_name(comp_id)); - ctx.write( - "result.insert({::", - cpp_comp_name, - "::id, ", - "&ecsact::entt::wrapper::core::update_component<::", - cpp_comp_name, - ">});\n" - ); - } - }); - - init_global(ctx, "remove_component_fns", [&] { - if(details.all_components.empty()) { - return; - } - - ctx.write("result.reserve(", details.all_components.size(), ");\n"); - - for(auto comp_id : details.all_components) { - auto cpp_comp_name = cpp_identifier(decl_full_name(comp_id)); - ctx.write( - "result.insert({::", - cpp_comp_name, - "::id, ", - "&ecsact::entt::wrapper::core::remove_component<::", - cpp_comp_name, - ">});\n" - ); - } - }); - - init_global(ctx, "has_component_fns", [&] { - if(details.all_components.empty()) { - return; - } - - ctx.write("result.reserve(", details.all_components.size(), ");\n"); - - for(auto comp_id : details.all_components) { - auto cpp_comp_name = cpp_identifier(decl_full_name(comp_id)); - ctx.write( - "result.insert({::", - cpp_comp_name, - "::id, ", - "&ecsact::entt::wrapper::core::has_component<::", - cpp_comp_name, - ">});\n" - ); - } - }); - - ctx.write("\n"); - - { // Print core Ecsact API methods - using namespace ecsact::rt_entt_codegen; - - core::print_check_error_template_specializations(ctx, details); - core::print_execute_system_like_template_specializations(ctx, details); - core::print_init_registry_storage(ctx, details); - core::print_create_registry(ctx, details); - core::print_trigger_ecsact_events_minimal(ctx, details); - core::print_trigger_ecsact_events_all(ctx, details); - core::print_cleanup_ecsact_component_events(ctx, details); - core::print_execution_options(ctx, details); - core::print_execute_systems(ctx, details); - } -} +#include +#include +#include +#include "core/core.hh" +#include "ecsact/runtime/meta.hh" +#include "ecsact/codegen/plugin.h" +#include "ecsact/codegen/plugin.hh" +#include "ecsact/lang-support/lang-cc.hh" + +#include "rt_entt_codegen/core/core.hh" +#include "rt_entt_codegen/shared/ecsact_entt_details.hh" +#include "shared/util.hh" + +constexpr auto GENERATED_FILE_DISCLAIMER = R"( +// GENERATED FILE - DO NOT EDIT +)"; + +constexpr auto MAIN_PACKAGE_ONLY_DISCLAIMER = R"( +// Purposely empty. ecsact_rt_entt_codegen is only for the 'main' package +)"; + +void ecsact_codegen_plugin( + ecsact_package_id package_id, + ecsact_codegen_write_fn_t write_fn +) { + using ecsact::cc_lang_support::c_identifier; + using ecsact::cc_lang_support::cpp_identifier; + using ecsact::meta::decl_full_name; + using ecsact::meta::get_all_system_like_ids; + using ecsact::rt_entt_codegen::ecsact_entt_details; + using ecsact::rt_entt_codegen::util::global_initializer_printer; + using ecsact::rt_entt_codegen::util::inc_header; + using ecsact::rt_entt_codegen::util::inc_package_header; + using ecsact::rt_entt_codegen::util::init_global; + + ecsact::codegen_plugin_context ctx{package_id, write_fn}; + + ctx.write(GENERATED_FILE_DISCLAIMER); + + if(ecsact_meta_main_package() != package_id) { + ctx.write(MAIN_PACKAGE_ONLY_DISCLAIMER); + return; + } + + auto details = ecsact_entt_details::from_package(package_id); + + inc_header(ctx, "ecsact/entt/entity.hh"); + inc_header(ctx, "ecsact/entt/event_markers.hh"); + inc_header(ctx, "ecsact/entt/execution.hh"); + 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/wrapper/core.hh"); + inc_header(ctx, "ecsact/entt/wrapper/dynamic.hh"); + inc_header(ctx, "ecsact/entt/error_check.hh"); + ctx.write("\n"); + inc_package_header(ctx, package_id); + for(auto dep : ecsact::meta::get_dependencies(package_id)) { + inc_package_header(ctx, dep); + } + ctx.write("\n"); + + init_global(ctx, "registries"); + init_global(ctx, "last_registry_id"); + init_global(ctx, "system_impls"); + + init_global(ctx, "all_component_ids", [&] { + if(details.all_components.empty()) { + return; + } + + ctx.write("result.reserve(", details.all_components.size(), ");\n"); + + for(auto comp_id : details.all_components) { + auto cpp_comp_name = cpp_identifier(decl_full_name(comp_id)); + ctx.write("result.insert(", cpp_comp_name, "::id);\n"); + } + }); + + init_global(ctx, "add_component_fns", [&] { + if(details.all_components.empty()) { + return; + } + + ctx.write("result.reserve(", details.all_components.size(), ");\n"); + + for(auto comp_id : details.all_components) { + auto cpp_comp_name = cpp_identifier(decl_full_name(comp_id)); + ctx.write( + "result.insert({::", + cpp_comp_name, + "::id, ", + "&ecsact::entt::wrapper::core::add_component<::", + cpp_comp_name, + ">});\n" + ); + } + }); + + init_global(ctx, "get_component_fns", [&] { + if(details.all_components.empty()) { + return; + } + + auto non_tag_component_ids = + details.all_components | + std::views::filter([&](ecsact_component_id comp_id) -> bool { + return !ecsact::meta::get_field_ids(comp_id).empty(); + }); + + ctx.write( + "result.reserve(", + std::ranges::distance(non_tag_component_ids), + ");\n" + ); + + for(auto comp_id : non_tag_component_ids) { + auto cpp_comp_name = cpp_identifier(decl_full_name(comp_id)); + ctx.write( + "result.insert({::", + cpp_comp_name, + "::id, ", + "&ecsact::entt::wrapper::core::get_component<::", + cpp_comp_name, + ">});\n" + ); + } + }); + + init_global(ctx, "update_component_fns", [&] { + if(details.all_components.empty()) { + return; + } + + auto non_tag_component_ids = + details.all_components | + std::views::filter([&](ecsact_component_id comp_id) -> bool { + return !ecsact::meta::get_field_ids(comp_id).empty(); + }); + + ctx.write( + "result.reserve(", + std::ranges::distance(non_tag_component_ids), + ");\n" + ); + + for(auto comp_id : non_tag_component_ids) { + auto cpp_comp_name = cpp_identifier(decl_full_name(comp_id)); + ctx.write( + "result.insert({::", + cpp_comp_name, + "::id, ", + "&ecsact::entt::wrapper::core::update_component<::", + cpp_comp_name, + ">});\n" + ); + } + }); + + init_global(ctx, "remove_component_fns", [&] { + if(details.all_components.empty()) { + return; + } + + ctx.write("result.reserve(", details.all_components.size(), ");\n"); + + for(auto comp_id : details.all_components) { + auto cpp_comp_name = cpp_identifier(decl_full_name(comp_id)); + ctx.write( + "result.insert({::", + cpp_comp_name, + "::id, ", + "&ecsact::entt::wrapper::core::remove_component<::", + cpp_comp_name, + ">});\n" + ); + } + }); + + init_global(ctx, "has_component_fns", [&] { + if(details.all_components.empty()) { + return; + } + + ctx.write("result.reserve(", details.all_components.size(), ");\n"); + + for(auto comp_id : details.all_components) { + auto cpp_comp_name = cpp_identifier(decl_full_name(comp_id)); + ctx.write( + "result.insert({::", + cpp_comp_name, + "::id, ", + "&ecsact::entt::wrapper::core::has_component<::", + cpp_comp_name, + ">});\n" + ); + } + }); + + ctx.write("\n"); + + { // Print core Ecsact API methods + using namespace ecsact::rt_entt_codegen; + + core::print_check_error_template_specializations(ctx, details); + core::print_execute_system_like_template_specializations(ctx, details); + core::print_init_registry_storage(ctx, details); + core::print_create_registry(ctx, details); + core::print_trigger_ecsact_events_minimal(ctx, details); + core::print_trigger_ecsact_events_all(ctx, details); + core::print_cleanup_ecsact_component_events(ctx, details); + core::print_execution_options(ctx, details); + core::print_execute_systems(ctx, details); + } +} diff --git a/rt_entt_codegen/shared/BUILD.bazel b/rt_entt_codegen/shared/BUILD.bazel index f71bea2..389c4a0 100644 --- a/rt_entt_codegen/shared/BUILD.bazel +++ b/rt_entt_codegen/shared/BUILD.bazel @@ -1,43 +1,43 @@ -load("@rules_cc//cc:defs.bzl", "cc_library") -load("//bazel:copts.bzl", "copts") - -package(default_visibility = ["//rt_entt_codegen:__subpackages__"]) - -cc_library( - name = "ecsact_entt_details", - srcs = ["ecsact_entt_details.cc"], - hdrs = ["ecsact_entt_details.hh"], - copts = copts, - defines = ["ECSACT_META_API_LOAD_AT_RUNTIME"], - deps = [ - "@ecsact_codegen//:plugin", - "@ecsact_lang_cpp//:support", - "@ecsact_runtime//:common", - "@ecsact_runtime//:meta", - ], -) - -cc_library( - name = "util", - hdrs = ["util.hh"], - copts = copts, - defines = ["ECSACT_META_API_LOAD_AT_RUNTIME"], - deps = [ - ":comps_with_caps", - "@ecsact_codegen//:plugin", - "@ecsact_lang_cpp//:support", - "@ecsact_runtime//:common", - "@ecsact_runtime//:meta", - ], -) - -cc_library( - name = "comps_with_caps", - hdrs = ["comps_with_caps.hh"], - copts = copts, - deps = [ - ":ecsact_entt_details", - "@ecsact_runtime//:common", - "@ecsact_runtime//:meta", - ], -) +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//bazel:copts.bzl", "copts") + +package(default_visibility = ["//rt_entt_codegen:__subpackages__"]) + +cc_library( + name = "ecsact_entt_details", + srcs = ["ecsact_entt_details.cc"], + hdrs = ["ecsact_entt_details.hh"], + copts = copts, + defines = ["ECSACT_META_API_LOAD_AT_RUNTIME"], + deps = [ + "@ecsact_codegen//:plugin", + "@ecsact_lang_cpp//:support", + "@ecsact_runtime//:common", + "@ecsact_runtime//:meta", + ], +) + +cc_library( + name = "util", + hdrs = ["util.hh"], + copts = copts, + defines = ["ECSACT_META_API_LOAD_AT_RUNTIME"], + deps = [ + ":comps_with_caps", + "@ecsact_codegen//:plugin", + "@ecsact_lang_cpp//:support", + "@ecsact_runtime//:common", + "@ecsact_runtime//:meta", + ], +) + +cc_library( + name = "comps_with_caps", + hdrs = ["comps_with_caps.hh"], + copts = copts, + deps = [ + ":ecsact_entt_details", + "@ecsact_runtime//:common", + "@ecsact_runtime//:meta", + ], +) diff --git a/rt_entt_codegen/shared/ecsact_entt_details.cc b/rt_entt_codegen/shared/ecsact_entt_details.cc index 25f0b26..76c40f5 100644 --- a/rt_entt_codegen/shared/ecsact_entt_details.cc +++ b/rt_entt_codegen/shared/ecsact_entt_details.cc @@ -1,203 +1,203 @@ -#include "ecsact_entt_details.hh" - -#include -#include "ecsact/codegen/plugin.h" -#include "ecsact/codegen/plugin.hh" -#include "ecsact/lang-support/lang-cc.hh" -#include "ecsact/runtime/meta.hh" -#include "rt_entt_codegen/shared/ecsact_entt_details.hh" - -using ecsact::rt_entt_codegen::ecsact_entt_details; -using ecsact::rt_entt_codegen::ecsact_entt_system_details; - -static auto collect_top_level_systems( // - ecsact_package_id pkg_id, - ecsact_entt_details& details -) -> void { - auto deps = ecsact::meta::get_dependencies(pkg_id); - for(auto dep : deps) { - auto tl_sys_ids = ecsact::meta::get_top_level_systems(dep); - details.top_execution_order.insert( - details.top_execution_order.end(), - tl_sys_ids.begin(), - tl_sys_ids.end() - ); - } - - auto main_tl_sys_ids = ecsact::meta::get_top_level_systems(pkg_id); - details.top_execution_order.insert( - details.top_execution_order.end(), - main_tl_sys_ids.begin(), - main_tl_sys_ids.end() - ); -} - -static auto collect_all_systems( // - ecsact_package_id pkg_id, - ecsact_entt_details& details -) -> void { - auto deps = ecsact::meta::get_dependencies(pkg_id); - for(auto dep : deps) { - for(auto id : ecsact::meta::get_system_ids(dep)) { - details.all_systems.insert(id); - } - } - - for(auto id : ecsact::meta::get_system_ids(pkg_id)) { - details.all_systems.insert(id); - } -} - -static auto collect_all_components( // - ecsact_package_id pkg_id, - ecsact_entt_details& details -) -> void { - auto deps = ecsact::meta::get_dependencies(pkg_id); - for(auto dep : deps) { - for(auto id : ecsact::meta::get_component_ids(dep)) { - details.all_components.insert(id); - } - } - - for(auto id : ecsact::meta::get_component_ids(pkg_id)) { - details.all_components.insert(id); - } -} - -static auto collect_all_actions( // - ecsact_package_id pkg_id, - ecsact_entt_details& details -) -> void { - auto deps = ecsact::meta::get_dependencies(pkg_id); - for(auto dep : deps) { - for(auto id : ecsact::meta::get_action_ids(dep)) { - details.all_actions.insert(id); - } - } - - for(auto id : ecsact::meta::get_action_ids(pkg_id)) { - details.all_actions.insert(id); - } -} - -auto ecsact_entt_system_details::fill_system_details( - ecsact_entt_system_details& out_details, - const std::unordered_map& - caps -) -> void { - for(auto&& [comp_id, cap] : caps) { - switch(cap) { - case ECSACT_SYS_CAP_INCLUDE: - out_details.get_comps.insert(comp_id); - break; - case ECSACT_SYS_CAP_READONLY: - out_details.get_comps.insert(comp_id); - out_details.readable_comps.insert(comp_id); - break; - case ECSACT_SYS_CAP_WRITEONLY: - out_details.get_comps.insert(comp_id); - out_details.writable_comps.insert(comp_id); - break; - case ECSACT_SYS_CAP_READWRITE: - out_details.get_comps.insert(comp_id); - out_details.readable_comps.insert(comp_id); - out_details.writable_comps.insert(comp_id); - break; - case ECSACT_SYS_CAP_OPTIONAL: - case ECSACT_SYS_CAP_OPTIONAL_READONLY: - case ECSACT_SYS_CAP_OPTIONAL_WRITEONLY: - case ECSACT_SYS_CAP_OPTIONAL_READWRITE: - assert(false && "optional unimplemented"); - break; - case ECSACT_SYS_CAP_REMOVES: - out_details.get_comps.insert(comp_id); - out_details.removable_comps.insert(comp_id); - break; - case ECSACT_SYS_CAP_EXCLUDE: - out_details.exclude_comps.insert(comp_id); - break; - case ECSACT_SYS_CAP_ADDS: - out_details.exclude_comps.insert(comp_id); - out_details.addable_comps.insert(comp_id); - break; - } - } - - for(auto&& [comp_id, _] : caps) { - // Santity check to make sure we've not missing any system comp IDs - assert( - out_details.get_comps.contains(comp_id) || - out_details.exclude_comps.contains(comp_id) - ); - } -} - -auto ecsact_entt_system_details::from_system_like( // - ecsact_system_like_id sys_like_id -) -> ecsact_entt_system_details { - auto details = ecsact_entt_system_details{}; - auto caps = ecsact::meta::system_capabilities(sys_like_id); - - fill_system_details(details, caps); - - for(auto comp_id : details.readable_comps) { - auto fields = ecsact::meta::system_association_fields(sys_like_id, comp_id); - for(auto field_id : fields) { - auto assoc_comps = ecsact::meta::system_association_capabilities( - sys_like_id, - comp_id, - field_id - ); - - details.association_details.insert( - details.association_details.end(), - association_info{ - .component_id = comp_id, - .field_id = field_id, - .capabilities = assoc_comps, - } - ); - } - } - - auto generate_ids = ecsact::meta::get_system_generates_ids(sys_like_id); - for(auto gen_id : generate_ids) { - auto gen_id_map = - ecsact::meta::get_system_generates_components(sys_like_id, gen_id); - details.generate_comps.emplace(details.generate_comps.end(), gen_id_map); - } - - return details; -} - -auto ecsact_entt_system_details::from_capabilities( // - std::unordered_map caps -) -> ecsact_entt_system_details { - // NOTE(Kelwan): This does not add generate behaviour or associations into - // details - auto details = ecsact_entt_system_details{}; - - fill_system_details(details, caps); - - return details; -} - -auto ecsact_entt_details::from_package( // - ecsact_package_id pkg_id -) -> ecsact_entt_details { - auto details = ecsact_entt_details{}; - - collect_top_level_systems(pkg_id, details); - collect_all_systems(pkg_id, details); - collect_all_actions(pkg_id, details); - collect_all_components(pkg_id, details); - - for(auto sys_id : details.top_execution_order) { - assert( - details.view_systems.contains(sys_id) || - details.group_systems.contains(sys_id) - ); - } - - return details; -} +#include "ecsact_entt_details.hh" + +#include +#include "ecsact/codegen/plugin.h" +#include "ecsact/codegen/plugin.hh" +#include "ecsact/lang-support/lang-cc.hh" +#include "ecsact/runtime/meta.hh" +#include "rt_entt_codegen/shared/ecsact_entt_details.hh" + +using ecsact::rt_entt_codegen::ecsact_entt_details; +using ecsact::rt_entt_codegen::ecsact_entt_system_details; + +static auto collect_top_level_systems( // + ecsact_package_id pkg_id, + ecsact_entt_details& details +) -> void { + auto deps = ecsact::meta::get_dependencies(pkg_id); + for(auto dep : deps) { + auto tl_sys_ids = ecsact::meta::get_top_level_systems(dep); + details.top_execution_order.insert( + details.top_execution_order.end(), + tl_sys_ids.begin(), + tl_sys_ids.end() + ); + } + + auto main_tl_sys_ids = ecsact::meta::get_top_level_systems(pkg_id); + details.top_execution_order.insert( + details.top_execution_order.end(), + main_tl_sys_ids.begin(), + main_tl_sys_ids.end() + ); +} + +static auto collect_all_systems( // + ecsact_package_id pkg_id, + ecsact_entt_details& details +) -> void { + auto deps = ecsact::meta::get_dependencies(pkg_id); + for(auto dep : deps) { + for(auto id : ecsact::meta::get_system_ids(dep)) { + details.all_systems.insert(id); + } + } + + for(auto id : ecsact::meta::get_system_ids(pkg_id)) { + details.all_systems.insert(id); + } +} + +static auto collect_all_components( // + ecsact_package_id pkg_id, + ecsact_entt_details& details +) -> void { + auto deps = ecsact::meta::get_dependencies(pkg_id); + for(auto dep : deps) { + for(auto id : ecsact::meta::get_component_ids(dep)) { + details.all_components.insert(id); + } + } + + for(auto id : ecsact::meta::get_component_ids(pkg_id)) { + details.all_components.insert(id); + } +} + +static auto collect_all_actions( // + ecsact_package_id pkg_id, + ecsact_entt_details& details +) -> void { + auto deps = ecsact::meta::get_dependencies(pkg_id); + for(auto dep : deps) { + for(auto id : ecsact::meta::get_action_ids(dep)) { + details.all_actions.insert(id); + } + } + + for(auto id : ecsact::meta::get_action_ids(pkg_id)) { + details.all_actions.insert(id); + } +} + +auto ecsact_entt_system_details::fill_system_details( + ecsact_entt_system_details& out_details, + const std::unordered_map& + caps +) -> void { + for(auto&& [comp_id, cap] : caps) { + switch(cap) { + case ECSACT_SYS_CAP_INCLUDE: + out_details.get_comps.insert(comp_id); + break; + case ECSACT_SYS_CAP_READONLY: + out_details.get_comps.insert(comp_id); + out_details.readable_comps.insert(comp_id); + break; + case ECSACT_SYS_CAP_WRITEONLY: + out_details.get_comps.insert(comp_id); + out_details.writable_comps.insert(comp_id); + break; + case ECSACT_SYS_CAP_READWRITE: + out_details.get_comps.insert(comp_id); + out_details.readable_comps.insert(comp_id); + out_details.writable_comps.insert(comp_id); + break; + case ECSACT_SYS_CAP_OPTIONAL: + case ECSACT_SYS_CAP_OPTIONAL_READONLY: + case ECSACT_SYS_CAP_OPTIONAL_WRITEONLY: + case ECSACT_SYS_CAP_OPTIONAL_READWRITE: + assert(false && "optional unimplemented"); + break; + case ECSACT_SYS_CAP_REMOVES: + out_details.get_comps.insert(comp_id); + out_details.removable_comps.insert(comp_id); + break; + case ECSACT_SYS_CAP_EXCLUDE: + out_details.exclude_comps.insert(comp_id); + break; + case ECSACT_SYS_CAP_ADDS: + out_details.exclude_comps.insert(comp_id); + out_details.addable_comps.insert(comp_id); + break; + } + } + + for(auto&& [comp_id, _] : caps) { + // Santity check to make sure we've not missing any system comp IDs + assert( + out_details.get_comps.contains(comp_id) || + out_details.exclude_comps.contains(comp_id) + ); + } +} + +auto ecsact_entt_system_details::from_system_like( // + ecsact_system_like_id sys_like_id +) -> ecsact_entt_system_details { + auto details = ecsact_entt_system_details{}; + auto caps = ecsact::meta::system_capabilities(sys_like_id); + + fill_system_details(details, caps); + + for(auto comp_id : details.readable_comps) { + auto fields = ecsact::meta::system_association_fields(sys_like_id, comp_id); + for(auto field_id : fields) { + auto assoc_comps = ecsact::meta::system_association_capabilities( + sys_like_id, + comp_id, + field_id + ); + + details.association_details.insert( + details.association_details.end(), + association_info{ + .component_id = comp_id, + .field_id = field_id, + .capabilities = assoc_comps, + } + ); + } + } + + auto generate_ids = ecsact::meta::get_system_generates_ids(sys_like_id); + for(auto gen_id : generate_ids) { + auto gen_id_map = + ecsact::meta::get_system_generates_components(sys_like_id, gen_id); + details.generate_comps.emplace(details.generate_comps.end(), gen_id_map); + } + + return details; +} + +auto ecsact_entt_system_details::from_capabilities( // + std::unordered_map caps +) -> ecsact_entt_system_details { + // NOTE(Kelwan): This does not add generate behaviour or associations into + // details + auto details = ecsact_entt_system_details{}; + + fill_system_details(details, caps); + + return details; +} + +auto ecsact_entt_details::from_package( // + ecsact_package_id pkg_id +) -> ecsact_entt_details { + auto details = ecsact_entt_details{}; + + collect_top_level_systems(pkg_id, details); + collect_all_systems(pkg_id, details); + collect_all_actions(pkg_id, details); + collect_all_components(pkg_id, details); + + for(auto sys_id : details.top_execution_order) { + assert( + details.view_systems.contains(sys_id) || + details.group_systems.contains(sys_id) + ); + } + + return details; +} diff --git a/rt_entt_codegen/shared/ecsact_entt_details.hh b/rt_entt_codegen/shared/ecsact_entt_details.hh index 7323077..8292380 100644 --- a/rt_entt_codegen/shared/ecsact_entt_details.hh +++ b/rt_entt_codegen/shared/ecsact_entt_details.hh @@ -1,102 +1,102 @@ -#pragma once - -#include -#include -#include -#include - -namespace ecsact::rt_entt_codegen { - -struct association_info { - ecsact_component_like_id component_id; - ecsact_field_id field_id; - std::unordered_map - capabilities; -}; - -struct other_key { - ecsact_component_like_id component_like_id; - ecsact_field_id field_id; - - auto operator<=>(const other_key& k) const = default; -}; - -using generate_t = - std::vector>; - -using association_t = std::vector; - -struct ecsact_entt_system_details { - /** Components/transients included in EnTT view/group */ - std::unordered_set get_comps; - - /** Components/transients excluded in EnTT view/group */ - std::unordered_set exclude_comps; - - /** Components this system is allowed to read */ - std::unordered_set readable_comps; - - /** Components this system is allowed to write */ - std::unordered_set writable_comps; - - /** Components this system is allowed to add */ - std::unordered_set addable_comps; - - /** Components this system is allowed to remove */ - std::unordered_set removable_comps; - - /** Components with an entity association*/ - association_t association_details; - - /** A map containing this system's generated component ids and its - * requirements*/ - generate_t generate_comps; - - static auto from_system_like( // - ecsact_system_like_id sys_like_id - ) -> ecsact_entt_system_details; - - static auto from_capabilities( // - std::unordered_map caps - ) -> ecsact_entt_system_details; - -private: - static auto fill_system_details( - ecsact_entt_system_details& in_details, - const std:: - unordered_map& caps - ) -> void; -}; - -/** - * Details about an the main Ecsact package in relation to EnTT runtime. Package - * dependencies are flattened. - */ -struct ecsact_entt_details { - static auto from_package(ecsact_package_id pkg_id) -> ecsact_entt_details; - - // Systems/actions we've decided will use an EnTT group - std::unordered_set group_systems; - - // Systems/actions we've decided will use an Entt view - std::unordered_set view_systems; - - // Top level sysetms/actions in execution order - std::vector top_execution_order; - - std::unordered_set all_systems; - - std::unordered_set all_actions; - - std::unordered_set all_components; - - inline auto is_action(ecsact_system_like_id id) const noexcept -> bool { - return all_actions.contains(static_cast(id)); - } - - inline auto is_system(ecsact_system_like_id id) const noexcept -> bool { - return all_systems.contains(static_cast(id)); - } -}; - -} // namespace ecsact::rt_entt_codegen +#pragma once + +#include +#include +#include +#include + +namespace ecsact::rt_entt_codegen { + +struct association_info { + ecsact_component_like_id component_id; + ecsact_field_id field_id; + std::unordered_map + capabilities; +}; + +struct other_key { + ecsact_component_like_id component_like_id; + ecsact_field_id field_id; + + auto operator<=>(const other_key& k) const = default; +}; + +using generate_t = + std::vector>; + +using association_t = std::vector; + +struct ecsact_entt_system_details { + /** Components/transients included in EnTT view/group */ + std::unordered_set get_comps; + + /** Components/transients excluded in EnTT view/group */ + std::unordered_set exclude_comps; + + /** Components this system is allowed to read */ + std::unordered_set readable_comps; + + /** Components this system is allowed to write */ + std::unordered_set writable_comps; + + /** Components this system is allowed to add */ + std::unordered_set addable_comps; + + /** Components this system is allowed to remove */ + std::unordered_set removable_comps; + + /** Components with an entity association*/ + association_t association_details; + + /** A map containing this system's generated component ids and its + * requirements*/ + generate_t generate_comps; + + static auto from_system_like( // + ecsact_system_like_id sys_like_id + ) -> ecsact_entt_system_details; + + static auto from_capabilities( // + std::unordered_map caps + ) -> ecsact_entt_system_details; + +private: + static auto fill_system_details( + ecsact_entt_system_details& in_details, + const std:: + unordered_map& caps + ) -> void; +}; + +/** + * Details about an the main Ecsact package in relation to EnTT runtime. Package + * dependencies are flattened. + */ +struct ecsact_entt_details { + static auto from_package(ecsact_package_id pkg_id) -> ecsact_entt_details; + + // Systems/actions we've decided will use an EnTT group + std::unordered_set group_systems; + + // Systems/actions we've decided will use an Entt view + std::unordered_set view_systems; + + // Top level sysetms/actions in execution order + std::vector top_execution_order; + + std::unordered_set all_systems; + + std::unordered_set all_actions; + + std::unordered_set all_components; + + inline auto is_action(ecsact_system_like_id id) const noexcept -> bool { + return all_actions.contains(static_cast(id)); + } + + inline auto is_system(ecsact_system_like_id id) const noexcept -> bool { + return all_systems.contains(static_cast(id)); + } +}; + +} // namespace ecsact::rt_entt_codegen diff --git a/rt_entt_codegen/shared/util.hh b/rt_entt_codegen/shared/util.hh index 2729a79..8f70450 100644 --- a/rt_entt_codegen/shared/util.hh +++ b/rt_entt_codegen/shared/util.hh @@ -1,249 +1,249 @@ -#pragma once - -#include -#include -#include -#include -#include "ecsact/codegen/plugin.hh" -#include "ecsact/lang-support/lang-cc.hh" -#include "ecsact/runtime/meta.hh" - -namespace ecsact::rt_entt_codegen::util { - -class global_initializer_printer { - bool disposed = false; - ecsact::codegen_plugin_context& ctx; - -public: - global_initializer_printer( - ecsact::codegen_plugin_context& ctx, - auto&& global_name - ) - : ctx(ctx) { - ctx.write( - "decltype(ecsact::entt::detail::globals::", - global_name, - ") ", - "ecsact::entt::detail::globals::", - global_name, - " = ", - "[]() -> " - "std::remove_cvref_t {" - ); - ctx.indentation += 1; - ctx.write("\n"); - ctx.write( - "auto result = " - "std::remove_cvref_t{};\n" - ); - } - - global_initializer_printer(global_initializer_printer&& other) - : ctx(other.ctx) { - disposed = other.disposed; - other.disposed = true; - } - - ~global_initializer_printer() { - if(disposed) { - return; - } - disposed = true; - ctx.write("return result;"); - ctx.indentation -= 1; - ctx.write("\n}();\n\n"); - } -}; - -template -inline auto decl_cpp_ident(DeclId id) -> std::string { - using ecsact::cc_lang_support::cpp_identifier; - using ecsact::meta::decl_full_name; - return "::" + cpp_identifier(decl_full_name(id)); -} - -inline auto init_global( // - ecsact::codegen_plugin_context& ctx, - auto&& global_name -) -> void { - // globals can only be initialized at the top - assert(ctx.indentation == 0); - - ctx.write( - "decltype(ecsact::entt::detail::globals::", - global_name, - ") ecsact::entt::detail::globals::", - global_name, - " = {};\n" - ); -} - -inline auto init_global( // - ecsact::codegen_plugin_context& ctx, - auto&& global_name, - auto&& body_fn -) -> void { - auto printer = global_initializer_printer{ctx, global_name}; - body_fn(); -} - -inline auto inc_header( // - ecsact::codegen_plugin_context& ctx, - auto&& header_path -) -> void { - ctx.write("#include \"", header_path, "\"\n"); -} - -inline auto inc_package_header( // - ecsact::codegen_plugin_context& ctx, - ecsact_package_id pkg_id -) -> void { - namespace fs = std::filesystem; - - auto main_ecsact_file_path = ecsact::meta::package_file_path(ctx.package_id); - if(ctx.package_id == pkg_id) { - main_ecsact_file_path.replace_extension( - main_ecsact_file_path.extension().string() + ".hh" - ); - - inc_header(ctx, main_ecsact_file_path.filename().string()); - } else { - auto cpp_header_path = ecsact::meta::package_file_path(pkg_id); - cpp_header_path.replace_extension( - cpp_header_path.extension().string() + ".hh" - ); - if(main_ecsact_file_path.has_parent_path()) { - cpp_header_path = - fs::relative(cpp_header_path, main_ecsact_file_path.parent_path()); - } - inc_header(ctx, cpp_header_path.filename().string()); - } -} - -inline auto is_transient_component( - ecsact_package_id package_id, - ecsact_component_like_id comp_id -) -> bool { - auto transient_ids = ecsact::meta::get_transient_ids(package_id); - for(auto transient_id : transient_ids) { - auto transient_component_like_id = - ecsact_id_cast(transient_id); - if(transient_component_like_id == comp_id) { - return true; - } - } - return false; -} - -class method_printer { - using parameters_list_t = std::vector>; - - bool disposed = false; - std::optional parameters; - ecsact::codegen_plugin_context& ctx; - - auto _parameter(std::string param_type, std::string param_name) -> void { - assert(!disposed); - if(disposed) { - return; - } - - assert( - parameters.has_value() && - "Cannot set parametrs after return type has been set" - ); - parameters->push_back({param_type, param_name}); - } - - auto _return_type(std::string type) { - assert(!disposed); - if(disposed) { - return; - } - - assert(parameters.has_value()); - if(!parameters.has_value()) { - return; - } - - if(!parameters->empty()) { - ctx.write("\n"); - } - - for(auto i = 0; parameters->size() > i; ++i) { - auto&& [param_type, param_name] = parameters->at(i); - ctx.write("\t", param_type, " ", param_name); - if(i + 1 < parameters->size()) { - ctx.write(","); - } - ctx.write("\n"); - } - - parameters = std::nullopt; - - ctx.write(") -> ", type, " {"); - ctx.indentation += 1; - ctx.write("\n"); - } - -public: - method_printer( // - ecsact::codegen_plugin_context& ctx, - std::string method_name - ) - : ctx(ctx) { - parameters.emplace(); - ctx.write("auto ", method_name, "("); - } - - method_printer(method_printer&& other) : ctx(other.ctx) { - disposed = other.disposed; - - if(!disposed) { - parameters = std::move(other.parameters); - } - - other.disposed = true; - } - - auto parameter( - std::string param_type, - std::string param_name - ) & -> method_printer& { - _parameter(param_type, param_name); - return *this; - } - - auto parameter( - std::string param_type, - std::string param_name - ) && -> method_printer { - _parameter(param_type, param_name); - return std::move(*this); - } - - auto return_type(std::string type) & -> method_printer& { - _return_type(type); - return *this; - } - - auto return_type(std::string type) && -> method_printer { - _return_type(type); - return std::move(*this); - } - - ~method_printer() { - if(disposed) { - return; - } - disposed = true; - ctx.indentation -= 1; - ctx.write("\n}\n\n"); - } -}; - -} // namespace ecsact::rt_entt_codegen::util +#pragma once + +#include +#include +#include +#include +#include "ecsact/codegen/plugin.hh" +#include "ecsact/lang-support/lang-cc.hh" +#include "ecsact/runtime/meta.hh" + +namespace ecsact::rt_entt_codegen::util { + +class global_initializer_printer { + bool disposed = false; + ecsact::codegen_plugin_context& ctx; + +public: + global_initializer_printer( + ecsact::codegen_plugin_context& ctx, + auto&& global_name + ) + : ctx(ctx) { + ctx.write( + "decltype(ecsact::entt::detail::globals::", + global_name, + ") ", + "ecsact::entt::detail::globals::", + global_name, + " = ", + "[]() -> " + "std::remove_cvref_t {" + ); + ctx.indentation += 1; + ctx.write("\n"); + ctx.write( + "auto result = " + "std::remove_cvref_t{};\n" + ); + } + + global_initializer_printer(global_initializer_printer&& other) + : ctx(other.ctx) { + disposed = other.disposed; + other.disposed = true; + } + + ~global_initializer_printer() { + if(disposed) { + return; + } + disposed = true; + ctx.write("return result;"); + ctx.indentation -= 1; + ctx.write("\n}();\n\n"); + } +}; + +template +inline auto decl_cpp_ident(DeclId id) -> std::string { + using ecsact::cc_lang_support::cpp_identifier; + using ecsact::meta::decl_full_name; + return "::" + cpp_identifier(decl_full_name(id)); +} + +inline auto init_global( // + ecsact::codegen_plugin_context& ctx, + auto&& global_name +) -> void { + // globals can only be initialized at the top + assert(ctx.indentation == 0); + + ctx.write( + "decltype(ecsact::entt::detail::globals::", + global_name, + ") ecsact::entt::detail::globals::", + global_name, + " = {};\n" + ); +} + +inline auto init_global( // + ecsact::codegen_plugin_context& ctx, + auto&& global_name, + auto&& body_fn +) -> void { + auto printer = global_initializer_printer{ctx, global_name}; + body_fn(); +} + +inline auto inc_header( // + ecsact::codegen_plugin_context& ctx, + auto&& header_path +) -> void { + ctx.write("#include \"", header_path, "\"\n"); +} + +inline auto inc_package_header( // + ecsact::codegen_plugin_context& ctx, + ecsact_package_id pkg_id +) -> void { + namespace fs = std::filesystem; + + auto main_ecsact_file_path = ecsact::meta::package_file_path(ctx.package_id); + if(ctx.package_id == pkg_id) { + main_ecsact_file_path.replace_extension( + main_ecsact_file_path.extension().string() + ".hh" + ); + + inc_header(ctx, main_ecsact_file_path.filename().string()); + } else { + auto cpp_header_path = ecsact::meta::package_file_path(pkg_id); + cpp_header_path.replace_extension( + cpp_header_path.extension().string() + ".hh" + ); + if(main_ecsact_file_path.has_parent_path()) { + cpp_header_path = + fs::relative(cpp_header_path, main_ecsact_file_path.parent_path()); + } + inc_header(ctx, cpp_header_path.filename().string()); + } +} + +inline auto is_transient_component( + ecsact_package_id package_id, + ecsact_component_like_id comp_id +) -> bool { + auto transient_ids = ecsact::meta::get_transient_ids(package_id); + for(auto transient_id : transient_ids) { + auto transient_component_like_id = + ecsact_id_cast(transient_id); + if(transient_component_like_id == comp_id) { + return true; + } + } + return false; +} + +class method_printer { + using parameters_list_t = std::vector>; + + bool disposed = false; + std::optional parameters; + ecsact::codegen_plugin_context& ctx; + + auto _parameter(std::string param_type, std::string param_name) -> void { + assert(!disposed); + if(disposed) { + return; + } + + assert( + parameters.has_value() && + "Cannot set parametrs after return type has been set" + ); + parameters->push_back({param_type, param_name}); + } + + auto _return_type(std::string type) { + assert(!disposed); + if(disposed) { + return; + } + + assert(parameters.has_value()); + if(!parameters.has_value()) { + return; + } + + if(!parameters->empty()) { + ctx.write("\n"); + } + + for(auto i = 0; parameters->size() > i; ++i) { + auto&& [param_type, param_name] = parameters->at(i); + ctx.write("\t", param_type, " ", param_name); + if(i + 1 < parameters->size()) { + ctx.write(","); + } + ctx.write("\n"); + } + + parameters = std::nullopt; + + ctx.write(") -> ", type, " {"); + ctx.indentation += 1; + ctx.write("\n"); + } + +public: + method_printer( // + ecsact::codegen_plugin_context& ctx, + std::string method_name + ) + : ctx(ctx) { + parameters.emplace(); + ctx.write("auto ", method_name, "("); + } + + method_printer(method_printer&& other) : ctx(other.ctx) { + disposed = other.disposed; + + if(!disposed) { + parameters = std::move(other.parameters); + } + + other.disposed = true; + } + + auto parameter( + std::string param_type, + std::string param_name + ) & -> method_printer& { + _parameter(param_type, param_name); + return *this; + } + + auto parameter( + std::string param_type, + std::string param_name + ) && -> method_printer { + _parameter(param_type, param_name); + return std::move(*this); + } + + auto return_type(std::string type) & -> method_printer& { + _return_type(type); + return *this; + } + + auto return_type(std::string type) && -> method_printer { + _return_type(type); + return std::move(*this); + } + + ~method_printer() { + if(disposed) { + return; + } + disposed = true; + ctx.indentation -= 1; + ctx.write("\n}\n\n"); + } +}; + +} // namespace ecsact::rt_entt_codegen::util diff --git a/runtime/ecsact_rt_entt_core.cc b/runtime/ecsact_rt_entt_core.cc index 75d51d0..8418c56 100644 --- a/runtime/ecsact_rt_entt_core.cc +++ b/runtime/ecsact_rt_entt_core.cc @@ -1,215 +1,215 @@ -/** - * This file contains _some_ of the Ecsact core module implementations. Other - * implementations are generated through the ecsact_rt_entt_codegen plugin. - * - * Generally speaking if the implementation requires any type information - * derived from the input Ecsact files they will not be defined here. - */ - -#include "ecsact/runtime/core.h" -#include "ecsact/entt/detail/globals.hh" -#include "ecsact/entt/registry_util.hh" -#include "ecsact/entt/entity.hh" - -void ecsact_destroy_registry(ecsact_registry_id reg_id) { - auto& reg = ecsact::entt::get_registry(reg_id); - reg = {}; - assert(reg.template storage().in_use() == 0); -} - -void ecsact_clear_registry(ecsact_registry_id reg_id) { - auto& reg = ecsact::entt::get_registry(reg_id); - reg = {}; - assert(reg.template storage().in_use() == 0); -} - -ecsact_entity_id ecsact_create_entity(ecsact_registry_id reg_id) { - auto& reg = ecsact::entt::get_registry(reg_id); - return ecsact::entt::entity_id{reg.create()}; -} - -void ecsact_ensure_entity( - ecsact_registry_id reg_id, - ecsact_entity_id entity_id -) { - auto entity = ecsact::entt::entity_id{entity_id}; - auto& reg = ecsact::entt::get_registry(reg_id); - if(!reg.valid(entity)) { - auto new_entity_id = ecsact::entt::entity_id{reg.create(entity)}; - assert(entity == new_entity_id); - } -} - -bool ecsact_entity_exists( - ecsact_registry_id reg_id, - ecsact_entity_id entity_id -) { - auto& reg = ecsact::entt::get_registry(reg_id); - return reg.valid(ecsact::entt::entity_id{entity_id}); -} - -void ecsact_destroy_entity( - ecsact_registry_id reg_id, - ecsact_entity_id entity_id -) { - auto& reg = ecsact::entt::get_registry(reg_id); - reg.destroy(ecsact::entt::entity_id{entity_id}); -} - -int ecsact_count_entities(ecsact_registry_id reg_id) { - auto& reg = ecsact::entt::get_registry(reg_id); - return static_cast(reg.template storage().in_use()); -} - -void ecsact_get_entities( - ecsact_registry_id reg_id, - int max_entities_count, - ecsact_entity_id* out_entities, - int* out_entities_count -) { - auto& reg = ecsact::entt::get_registry(reg_id); - - int entities_count = - static_cast(reg.template storage().in_use()); - max_entities_count = std::min(entities_count, max_entities_count); - - { - // TODO(zaucy): Using `info.registry.each` is poor when max entities - // count is less than the amount of entities in the registry. - // Replace with a different fn such `as info.registry.data` - int i = 0; - - for(auto&& [entity_id] : reg.template storage().each()) { - if(i >= max_entities_count) { - return; - } - - out_entities[i] = ecsact::entt::entity_id{entity_id}; - ++i; - } - } - - if(out_entities_count != nullptr) { - *out_entities_count = entities_count; - } -} - -ecsact_add_error ecsact_add_component( - ecsact_registry_id reg_id, - ecsact_entity_id entity_id, - ecsact_component_id component_id, - const void* component_data -) { - using ecsact::entt::detail::globals::add_component_fns; - auto fn_itr = add_component_fns.find(component_id); - assert(fn_itr != add_component_fns.end()); - return fn_itr->second(reg_id, entity_id, component_id, component_data); -} - -bool ecsact_has_component( - ecsact_registry_id reg_id, - ecsact_entity_id entity_id, - ecsact_component_id component_id -) { - using ecsact::entt::detail::globals::has_component_fns; - auto fn_itr = has_component_fns.find(component_id); - assert(fn_itr != has_component_fns.end()); - return fn_itr->second(reg_id, entity_id, component_id); -} - -const void* ecsact_get_component( - ecsact_registry_id reg_id, - ecsact_entity_id entity_id, - ecsact_component_id component_id -) { - using ecsact::entt::detail::globals::get_component_fns; - auto fn_itr = get_component_fns.find(component_id); - assert(fn_itr != get_component_fns.end()); - return fn_itr->second(reg_id, entity_id, component_id); -} - -int ecsact_count_components( - ecsact_registry_id registry_id, - ecsact_entity_id entity_id -) { - using ecsact::entt::detail::globals::all_component_ids; - - int component_count = 0; - for(auto comp_id : all_component_ids) { - if(ecsact_has_component(registry_id, entity_id, comp_id)) { - component_count += 1; - } - } - return component_count; -} - -void ecsact_each_component( - ecsact_registry_id registry_id, - ecsact_entity_id entity_id, - ecsact_each_component_callback callback, - void* callback_user_data -) { - using ecsact::entt::detail::globals::all_component_ids; - - for(auto comp_id : all_component_ids) { - if(ecsact_has_component(registry_id, entity_id, comp_id)) { - callback( - comp_id, - ecsact_get_component(registry_id, entity_id, comp_id), - callback_user_data - ); - } - } -} - -void ecsact_get_components( - ecsact_registry_id registry_id, - ecsact_entity_id entity_id, - int max_components_count, - ecsact_component_id* out_component_ids, - const void** out_components_data, - int* out_components_count -) { - using ecsact::entt::detail::globals::all_component_ids; - - auto index = 0; - for(auto comp_id : all_component_ids) { - if(index >= max_components_count) { - break; - } - - if(ecsact_has_component(registry_id, entity_id, comp_id)) { - out_component_ids[index] = comp_id; - out_components_data[index] = - ecsact_get_component(registry_id, entity_id, comp_id); - index += 1; - } - } - - if(out_components_count != nullptr) { - *out_components_count = index; - } -} - -ecsact_update_error ecsact_update_component( - ecsact_registry_id reg_id, - ecsact_entity_id entity_id, - ecsact_component_id component_id, - const void* component_data -) { - using ecsact::entt::detail::globals::update_component_fns; - auto fn_itr = update_component_fns.find(component_id); - assert(fn_itr != update_component_fns.end()); - return fn_itr->second(reg_id, entity_id, component_id, component_data); -} - -void ecsact_remove_component( - ecsact_registry_id reg_id, - ecsact_entity_id entity_id, - ecsact_component_id component_id -) { - using ecsact::entt::detail::globals::remove_component_fns; - auto fn_itr = remove_component_fns.find(component_id); - assert(fn_itr != remove_component_fns.end()); - return fn_itr->second(reg_id, entity_id, component_id); -} +/** + * This file contains _some_ of the Ecsact core module implementations. Other + * implementations are generated through the ecsact_rt_entt_codegen plugin. + * + * Generally speaking if the implementation requires any type information + * derived from the input Ecsact files they will not be defined here. + */ + +#include "ecsact/runtime/core.h" +#include "ecsact/entt/detail/globals.hh" +#include "ecsact/entt/registry_util.hh" +#include "ecsact/entt/entity.hh" + +void ecsact_destroy_registry(ecsact_registry_id reg_id) { + auto& reg = ecsact::entt::get_registry(reg_id); + reg = {}; + assert(reg.template storage().in_use() == 0); +} + +void ecsact_clear_registry(ecsact_registry_id reg_id) { + auto& reg = ecsact::entt::get_registry(reg_id); + reg = {}; + assert(reg.template storage().in_use() == 0); +} + +ecsact_entity_id ecsact_create_entity(ecsact_registry_id reg_id) { + auto& reg = ecsact::entt::get_registry(reg_id); + return ecsact::entt::entity_id{reg.create()}; +} + +void ecsact_ensure_entity( + ecsact_registry_id reg_id, + ecsact_entity_id entity_id +) { + auto entity = ecsact::entt::entity_id{entity_id}; + auto& reg = ecsact::entt::get_registry(reg_id); + if(!reg.valid(entity)) { + auto new_entity_id = ecsact::entt::entity_id{reg.create(entity)}; + assert(entity == new_entity_id); + } +} + +bool ecsact_entity_exists( + ecsact_registry_id reg_id, + ecsact_entity_id entity_id +) { + auto& reg = ecsact::entt::get_registry(reg_id); + return reg.valid(ecsact::entt::entity_id{entity_id}); +} + +void ecsact_destroy_entity( + ecsact_registry_id reg_id, + ecsact_entity_id entity_id +) { + auto& reg = ecsact::entt::get_registry(reg_id); + reg.destroy(ecsact::entt::entity_id{entity_id}); +} + +int ecsact_count_entities(ecsact_registry_id reg_id) { + auto& reg = ecsact::entt::get_registry(reg_id); + return static_cast(reg.template storage().in_use()); +} + +void ecsact_get_entities( + ecsact_registry_id reg_id, + int max_entities_count, + ecsact_entity_id* out_entities, + int* out_entities_count +) { + auto& reg = ecsact::entt::get_registry(reg_id); + + int entities_count = + static_cast(reg.template storage().in_use()); + max_entities_count = std::min(entities_count, max_entities_count); + + { + // TODO(zaucy): Using `info.registry.each` is poor when max entities + // count is less than the amount of entities in the registry. + // Replace with a different fn such `as info.registry.data` + int i = 0; + + for(auto&& [entity_id] : reg.template storage().each()) { + if(i >= max_entities_count) { + return; + } + + out_entities[i] = ecsact::entt::entity_id{entity_id}; + ++i; + } + } + + if(out_entities_count != nullptr) { + *out_entities_count = entities_count; + } +} + +ecsact_add_error ecsact_add_component( + ecsact_registry_id reg_id, + ecsact_entity_id entity_id, + ecsact_component_id component_id, + const void* component_data +) { + using ecsact::entt::detail::globals::add_component_fns; + auto fn_itr = add_component_fns.find(component_id); + assert(fn_itr != add_component_fns.end()); + return fn_itr->second(reg_id, entity_id, component_id, component_data); +} + +bool ecsact_has_component( + ecsact_registry_id reg_id, + ecsact_entity_id entity_id, + ecsact_component_id component_id +) { + using ecsact::entt::detail::globals::has_component_fns; + auto fn_itr = has_component_fns.find(component_id); + assert(fn_itr != has_component_fns.end()); + return fn_itr->second(reg_id, entity_id, component_id); +} + +const void* ecsact_get_component( + ecsact_registry_id reg_id, + ecsact_entity_id entity_id, + ecsact_component_id component_id +) { + using ecsact::entt::detail::globals::get_component_fns; + auto fn_itr = get_component_fns.find(component_id); + assert(fn_itr != get_component_fns.end()); + return fn_itr->second(reg_id, entity_id, component_id); +} + +int ecsact_count_components( + ecsact_registry_id registry_id, + ecsact_entity_id entity_id +) { + using ecsact::entt::detail::globals::all_component_ids; + + int component_count = 0; + for(auto comp_id : all_component_ids) { + if(ecsact_has_component(registry_id, entity_id, comp_id)) { + component_count += 1; + } + } + return component_count; +} + +void ecsact_each_component( + ecsact_registry_id registry_id, + ecsact_entity_id entity_id, + ecsact_each_component_callback callback, + void* callback_user_data +) { + using ecsact::entt::detail::globals::all_component_ids; + + for(auto comp_id : all_component_ids) { + if(ecsact_has_component(registry_id, entity_id, comp_id)) { + callback( + comp_id, + ecsact_get_component(registry_id, entity_id, comp_id), + callback_user_data + ); + } + } +} + +void ecsact_get_components( + ecsact_registry_id registry_id, + ecsact_entity_id entity_id, + int max_components_count, + ecsact_component_id* out_component_ids, + const void** out_components_data, + int* out_components_count +) { + using ecsact::entt::detail::globals::all_component_ids; + + auto index = 0; + for(auto comp_id : all_component_ids) { + if(index >= max_components_count) { + break; + } + + if(ecsact_has_component(registry_id, entity_id, comp_id)) { + out_component_ids[index] = comp_id; + out_components_data[index] = + ecsact_get_component(registry_id, entity_id, comp_id); + index += 1; + } + } + + if(out_components_count != nullptr) { + *out_components_count = index; + } +} + +ecsact_update_error ecsact_update_component( + ecsact_registry_id reg_id, + ecsact_entity_id entity_id, + ecsact_component_id component_id, + const void* component_data +) { + using ecsact::entt::detail::globals::update_component_fns; + auto fn_itr = update_component_fns.find(component_id); + assert(fn_itr != update_component_fns.end()); + return fn_itr->second(reg_id, entity_id, component_id, component_data); +} + +void ecsact_remove_component( + ecsact_registry_id reg_id, + ecsact_entity_id entity_id, + ecsact_component_id component_id +) { + using ecsact::entt::detail::globals::remove_component_fns; + auto fn_itr = remove_component_fns.find(component_id); + assert(fn_itr != remove_component_fns.end()); + return fn_itr->second(reg_id, entity_id, component_id); +}