diff --git a/ecsact/runtime/common.h b/ecsact/runtime/common.h index c5a087b0..44521d5f 100644 --- a/ecsact/runtime/common.h +++ b/ecsact/runtime/common.h @@ -532,6 +532,13 @@ typedef struct ecsact_execution_options { */ ecsact_component* update_components; + /** + * Sequential list of indexed field values for the given `update_components`. + * Length is determined by `update_components_length * + * update-components-total-indexed-fields-count`. + */ + const void** update_components_indexed_fields; + /** * Length of `remove_components_entities` and `remove_components` sequential * lists. @@ -552,6 +559,13 @@ typedef struct ecsact_execution_options { */ ecsact_component_id* remove_components; + /** + * Sequential list of indexed field values for the given `remove_components`. + * Length is determined by `remove_components_length * + * remove-components-total-indexed-fields-count`. + */ + const void** remove_components_indexed_fields; + /** * Length of `actions` sequential list. */ diff --git a/ecsact/runtime/core.h b/ecsact/runtime/core.h index c0ebf9c4..e8efd8c0 100644 --- a/ecsact/runtime/core.h +++ b/ecsact/runtime/core.h @@ -115,7 +115,7 @@ ECSACT_CORE_API_FN(void, ecsact_get_entities) /** * Adds a component to the specified entity. * - * @note This method should be avoided if possible. Adding a component in a + * NOTE: This method should be avoided if possible. Adding a component in a * system or system execution options is preferred. * SEE: `ecsact_execute_systems` */ @@ -127,22 +127,31 @@ ECSACT_CORE_API_FN(ecsact_add_error, ecsact_add_component) const void* component_data ); +/** + * Checks if a given entity has component with id @p component_id + * @param ... if the component has indexed fields then those fields must be + * supplied to the variadic arguments in declaration order. + */ ECSACT_CORE_API_FN(bool, ecsact_has_component) ( // ecsact_registry_id registry_id, ecsact_entity_id entity_id, - ecsact_component_id component_id + ecsact_component_id component_id, + ... ); /** + * @param ... if the component has indexed fields then those fields must be + * supplied to the variadic arguments in declaration order. * @returns non-owning pointer of the component data - * @note This method should be avoided if possible. + * NOTE: This method should be avoided if possible. */ ECSACT_CORE_API_FN(const void*, ecsact_get_component) ( // ecsact_registry_id registry_id, ecsact_entity_id entity_id, - ecsact_component_id component_id + ecsact_component_id component_id, + ... ); /** @@ -184,7 +193,10 @@ ECSACT_CORE_API_FN(void, ecsact_each_component) /** * Update a component for the specified entity. * - * @note This method should be avoided if possible. Updating a component in a + * @param ... if the component has indexed fields then those fields must be + * supplied to the variadic arguments in declaration order. + * + * NOTE: This method should be avoided if possible. Updating a component in a * system or system execution options is preferred. * SEE: `ecsact_execute_systems` */ @@ -193,13 +205,17 @@ ECSACT_CORE_API_FN(ecsact_update_error, ecsact_update_component) ecsact_registry_id registry_id, ecsact_entity_id entity_id, ecsact_component_id component_id, - const void* component_data + const void* component_data, + ... ); /** * Removes a component from the specified entity. * - * @note This method should be avoided if possible. Removing a component in a + * @param ... if the component has indexed fields then those fields must be + * supplied to the variadic arguments in declaration order. + * + * NOTE: This method should be avoided if possible. Removing a component in a * system or system execution options is preferred. * SEE: `ecsact_execute_systems` */ @@ -207,7 +223,8 @@ ECSACT_CORE_API_FN(void, ecsact_remove_component) ( // ecsact_registry_id registry_id, ecsact_entity_id entity_id, - ecsact_component_id component_id + ecsact_component_id component_id, + ... ); /** diff --git a/ecsact/runtime/core.hh b/ecsact/runtime/core.hh index 1bf6f36a..01f8104a 100644 --- a/ecsact/runtime/core.hh +++ b/ecsact/runtime/core.hh @@ -635,19 +635,45 @@ public: return ecsact_create_entity(_id); } - template + template requires(!std::is_empty_v) ECSACT_ALWAYS_INLINE auto get_component( // - ecsact_entity_id entity_id + ecsact_entity_id entity_id, + AssocFields&&... assoc_fields ) -> const Component& { - return *reinterpret_cast( - ecsact_get_component(_id, entity_id, Component::id) - ); + if constexpr(Component::has_assoc_fields) { + static_assert( + sizeof...(AssocFields) > 0, + "must be called with assoc fields" + ); + } + + return *reinterpret_cast(ecsact_get_component( + _id, + entity_id, + Component::id, + std::forward(assoc_fields)... + )); } - template - ECSACT_ALWAYS_INLINE bool has_component(ecsact_entity_id entity_id) { - return ecsact_has_component(_id, entity_id, Component::id); + template + ECSACT_ALWAYS_INLINE bool has_component( + ecsact_entity_id entity_id, + AssocFields&&... assoc_fields + ) { + if constexpr(Component::has_assoc_fields) { + static_assert( + sizeof...(AssocFields) > 0, + "must be called with assoc fields" + ); + } + + return ecsact_has_component( + _id, + entity_id, + Component::id, + std::forward(assoc_fields)... + ); } template @@ -668,12 +694,46 @@ public: } } - template + template ECSACT_ALWAYS_INLINE auto update_component( ecsact_entity_id entity_id, - const Component& component + const Component& component, + AssocFields&&... assoc_fields ) { - return ecsact_update_component(_id, entity_id, Component::id, &component); + if constexpr(Component::has_assoc_fields) { + static_assert( + sizeof...(AssocFields) > 0, + "must be called with assoc fields" + ); + } + + return ecsact_update_component( + _id, + entity_id, + Component::id, + &component, + std::forward(assoc_fields)... + ); + } + + template + ECSACT_ALWAYS_INLINE auto remove_component( + ecsact_entity_id entity_id, + AssocFields&&... assoc_fields + ) -> void { + if constexpr(Component::has_assoc_fields) { + static_assert( + sizeof...(AssocFields) > 0, + "must be called with assoc fields" + ); + } + + return ecsact_remove_component( + _id, + entity_id, + Component::id, + std::forward(assoc_fields)... + ); } ECSACT_ALWAYS_INLINE auto count_entities() const -> int32_t { diff --git a/ecsact/runtime/dynamic.h b/ecsact/runtime/dynamic.h index 7c316110..d38fdb83 100644 --- a/ecsact/runtime/dynamic.h +++ b/ecsact/runtime/dynamic.h @@ -57,11 +57,15 @@ ECSACT_DYNAMIC_API_FN(void, ecsact_system_execution_context_add) * * Only available if has one of these capabilities: * - `ECSACT_SYS_CAP_REMOVES` + * + * @param ... if the component has indexed fields then those fields must be + * supplied to the variadic arguments in declaration order. */ ECSACT_DYNAMIC_API_FN(void, ecsact_system_execution_context_remove) ( // struct ecsact_system_execution_context* context, - ecsact_component_like_id component_id + ecsact_component_like_id component_id, + ... ); /** @@ -76,12 +80,16 @@ ECSACT_DYNAMIC_API_FN(void, ecsact_system_execution_context_remove) * - `ECSACT_SYS_CAP_READWRITE` * - `ECSACT_SYS_CAP_OPTIONAL_READONLY` * - `ECSACT_SYS_CAP_OPTIONAL_READWRITE` + * + * @param ... if the component has indexed fields then those fields must be + * supplied to the variadic arguments in declaration order. */ ECSACT_DYNAMIC_API_FN(void, ecsact_system_execution_context_get) ( // struct ecsact_system_execution_context* context, ecsact_component_like_id component_id, - void* out_component_data + void* out_component_data, + ... ); /** @@ -90,12 +98,16 @@ ECSACT_DYNAMIC_API_FN(void, ecsact_system_execution_context_get) * - `ECSACT_SYS_CAP_READWRITE` * - `ECSACT_SYS_CAP_OPTIONAL_WRITEONLY` * - `ECSACT_SYS_CAP_OPTIONAL_READWRITE` + * + * @param ... if the component has indexed fields then those fields must be + * supplied to the variadic arguments in declaration order. */ ECSACT_DYNAMIC_API_FN(void, ecsact_system_execution_context_update) ( // struct ecsact_system_execution_context* context, ecsact_component_like_id component_id, - const void* component_data + const void* component_data, + ... ); /** @@ -106,11 +118,15 @@ ECSACT_DYNAMIC_API_FN(void, ecsact_system_execution_context_update) * - `ECSACT_SYS_CAP_OPTIONAL_READONLY` * - `ECSACT_SYS_CAP_OPTIONAL_WRITEONLY` * - `ECSACT_SYS_CAP_OPTIONAL_READWRITE` + * + * @param ... if the component has indexed fields then those fields must be + * supplied to the variadic arguments in declaration order. */ ECSACT_DYNAMIC_API_FN(bool, ecsact_system_execution_context_has) ( // struct ecsact_system_execution_context* context, - ecsact_component_like_id component_id + ecsact_component_like_id component_id, + ... ); /**