Skip to content

Commit

Permalink
feat: indexed fields multi-add api (#255)
Browse files Browse the repository at this point in the history
  • Loading branch information
zaucy authored Jun 27, 2024
1 parent 5d9f5e6 commit 64b81d7
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 23 deletions.
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

0 comments on commit 64b81d7

Please sign in to comment.