Skip to content

feat: indexed fields multi-add api #255

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions ecsact/runtime/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
*/
Expand Down
33 changes: 25 additions & 8 deletions ecsact/runtime/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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`
*/
Expand All @@ -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,
...
);

/**
Expand Down Expand Up @@ -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`
*/
Expand All @@ -193,21 +205,26 @@ 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`
*/
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,
...
);

/**
Expand Down
82 changes: 71 additions & 11 deletions ecsact/runtime/core.hh
Original file line number Diff line number Diff line change
Expand Up @@ -635,19 +635,45 @@ public:
return ecsact_create_entity(_id);
}

template<typename Component>
template<typename Component, typename... AssocFields>
requires(!std::is_empty_v<Component>)
ECSACT_ALWAYS_INLINE auto get_component( //
ecsact_entity_id entity_id
ecsact_entity_id entity_id,
AssocFields&&... assoc_fields
) -> const Component& {
return *reinterpret_cast<const Component*>(
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<const Component*>(ecsact_get_component(
_id,
entity_id,
Component::id,
std::forward<AssocFields>(assoc_fields)...
));
}

template<typename Component>
ECSACT_ALWAYS_INLINE bool has_component(ecsact_entity_id entity_id) {
return ecsact_has_component(_id, entity_id, Component::id);
template<typename Component, typename... AssocFields>
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<AssocFields>(assoc_fields)...
);
}

template<typename Component>
Expand All @@ -668,12 +694,46 @@ public:
}
}

template<typename Component>
template<typename Component, typename... AssocFields>
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<AssocFields>(assoc_fields)...
);
}

template<typename Component, typename... AssocFields>
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<AssocFields>(assoc_fields)...
);
}

ECSACT_ALWAYS_INLINE auto count_entities() const -> int32_t {
Expand Down
24 changes: 20 additions & 4 deletions ecsact/runtime/dynamic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
...
);

/**
Expand All @@ -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,
...
);

/**
Expand All @@ -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,
...
);

/**
Expand All @@ -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,
...
);

/**
Expand Down
Loading