Skip to content

Commit 64b81d7

Browse files
authored
feat: indexed fields multi-add api (#255)
1 parent 5d9f5e6 commit 64b81d7

File tree

4 files changed

+130
-23
lines changed

4 files changed

+130
-23
lines changed

ecsact/runtime/common.h

+14
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,13 @@ typedef struct ecsact_execution_options {
532532
*/
533533
ecsact_component* update_components;
534534

535+
/**
536+
* Sequential list of indexed field values for the given `update_components`.
537+
* Length is determined by `update_components_length *
538+
* update-components-total-indexed-fields-count`.
539+
*/
540+
const void** update_components_indexed_fields;
541+
535542
/**
536543
* Length of `remove_components_entities` and `remove_components` sequential
537544
* lists.
@@ -552,6 +559,13 @@ typedef struct ecsact_execution_options {
552559
*/
553560
ecsact_component_id* remove_components;
554561

562+
/**
563+
* Sequential list of indexed field values for the given `remove_components`.
564+
* Length is determined by `remove_components_length *
565+
* remove-components-total-indexed-fields-count`.
566+
*/
567+
const void** remove_components_indexed_fields;
568+
555569
/**
556570
* Length of `actions` sequential list.
557571
*/

ecsact/runtime/core.h

+25-8
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ ECSACT_CORE_API_FN(void, ecsact_get_entities)
115115
/**
116116
* Adds a component to the specified entity.
117117
*
118-
* @note This method should be avoided if possible. Adding a component in a
118+
* NOTE: This method should be avoided if possible. Adding a component in a
119119
* system or system execution options is preferred.
120120
* SEE: `ecsact_execute_systems`
121121
*/
@@ -127,22 +127,31 @@ ECSACT_CORE_API_FN(ecsact_add_error, ecsact_add_component)
127127
const void* component_data
128128
);
129129

130+
/**
131+
* Checks if a given entity has component with id @p component_id
132+
* @param ... if the component has indexed fields then those fields must be
133+
* supplied to the variadic arguments in declaration order.
134+
*/
130135
ECSACT_CORE_API_FN(bool, ecsact_has_component)
131136
( //
132137
ecsact_registry_id registry_id,
133138
ecsact_entity_id entity_id,
134-
ecsact_component_id component_id
139+
ecsact_component_id component_id,
140+
...
135141
);
136142

137143
/**
144+
* @param ... if the component has indexed fields then those fields must be
145+
* supplied to the variadic arguments in declaration order.
138146
* @returns non-owning pointer of the component data
139-
* @note This method should be avoided if possible.
147+
* NOTE: This method should be avoided if possible.
140148
*/
141149
ECSACT_CORE_API_FN(const void*, ecsact_get_component)
142150
( //
143151
ecsact_registry_id registry_id,
144152
ecsact_entity_id entity_id,
145-
ecsact_component_id component_id
153+
ecsact_component_id component_id,
154+
...
146155
);
147156

148157
/**
@@ -184,7 +193,10 @@ ECSACT_CORE_API_FN(void, ecsact_each_component)
184193
/**
185194
* Update a component for the specified entity.
186195
*
187-
* @note This method should be avoided if possible. Updating a component in a
196+
* @param ... if the component has indexed fields then those fields must be
197+
* supplied to the variadic arguments in declaration order.
198+
*
199+
* NOTE: This method should be avoided if possible. Updating a component in a
188200
* system or system execution options is preferred.
189201
* SEE: `ecsact_execute_systems`
190202
*/
@@ -193,21 +205,26 @@ ECSACT_CORE_API_FN(ecsact_update_error, ecsact_update_component)
193205
ecsact_registry_id registry_id,
194206
ecsact_entity_id entity_id,
195207
ecsact_component_id component_id,
196-
const void* component_data
208+
const void* component_data,
209+
...
197210
);
198211

199212
/**
200213
* Removes a component from the specified entity.
201214
*
202-
* @note This method should be avoided if possible. Removing a component in a
215+
* @param ... if the component has indexed fields then those fields must be
216+
* supplied to the variadic arguments in declaration order.
217+
*
218+
* NOTE: This method should be avoided if possible. Removing a component in a
203219
* system or system execution options is preferred.
204220
* SEE: `ecsact_execute_systems`
205221
*/
206222
ECSACT_CORE_API_FN(void, ecsact_remove_component)
207223
( //
208224
ecsact_registry_id registry_id,
209225
ecsact_entity_id entity_id,
210-
ecsact_component_id component_id
226+
ecsact_component_id component_id,
227+
...
211228
);
212229

213230
/**

ecsact/runtime/core.hh

+71-11
Original file line numberDiff line numberDiff line change
@@ -635,19 +635,45 @@ public:
635635
return ecsact_create_entity(_id);
636636
}
637637

638-
template<typename Component>
638+
template<typename Component, typename... AssocFields>
639639
requires(!std::is_empty_v<Component>)
640640
ECSACT_ALWAYS_INLINE auto get_component( //
641-
ecsact_entity_id entity_id
641+
ecsact_entity_id entity_id,
642+
AssocFields&&... assoc_fields
642643
) -> const Component& {
643-
return *reinterpret_cast<const Component*>(
644-
ecsact_get_component(_id, entity_id, Component::id)
645-
);
644+
if constexpr(Component::has_assoc_fields) {
645+
static_assert(
646+
sizeof...(AssocFields) > 0,
647+
"must be called with assoc fields"
648+
);
649+
}
650+
651+
return *reinterpret_cast<const Component*>(ecsact_get_component(
652+
_id,
653+
entity_id,
654+
Component::id,
655+
std::forward<AssocFields>(assoc_fields)...
656+
));
646657
}
647658

648-
template<typename Component>
649-
ECSACT_ALWAYS_INLINE bool has_component(ecsact_entity_id entity_id) {
650-
return ecsact_has_component(_id, entity_id, Component::id);
659+
template<typename Component, typename... AssocFields>
660+
ECSACT_ALWAYS_INLINE bool has_component(
661+
ecsact_entity_id entity_id,
662+
AssocFields&&... assoc_fields
663+
) {
664+
if constexpr(Component::has_assoc_fields) {
665+
static_assert(
666+
sizeof...(AssocFields) > 0,
667+
"must be called with assoc fields"
668+
);
669+
}
670+
671+
return ecsact_has_component(
672+
_id,
673+
entity_id,
674+
Component::id,
675+
std::forward<AssocFields>(assoc_fields)...
676+
);
651677
}
652678

653679
template<typename Component>
@@ -668,12 +694,46 @@ public:
668694
}
669695
}
670696

671-
template<typename Component>
697+
template<typename Component, typename... AssocFields>
672698
ECSACT_ALWAYS_INLINE auto update_component(
673699
ecsact_entity_id entity_id,
674-
const Component& component
700+
const Component& component,
701+
AssocFields&&... assoc_fields
675702
) {
676-
return ecsact_update_component(_id, entity_id, Component::id, &component);
703+
if constexpr(Component::has_assoc_fields) {
704+
static_assert(
705+
sizeof...(AssocFields) > 0,
706+
"must be called with assoc fields"
707+
);
708+
}
709+
710+
return ecsact_update_component(
711+
_id,
712+
entity_id,
713+
Component::id,
714+
&component,
715+
std::forward<AssocFields>(assoc_fields)...
716+
);
717+
}
718+
719+
template<typename Component, typename... AssocFields>
720+
ECSACT_ALWAYS_INLINE auto remove_component(
721+
ecsact_entity_id entity_id,
722+
AssocFields&&... assoc_fields
723+
) -> void {
724+
if constexpr(Component::has_assoc_fields) {
725+
static_assert(
726+
sizeof...(AssocFields) > 0,
727+
"must be called with assoc fields"
728+
);
729+
}
730+
731+
return ecsact_remove_component(
732+
_id,
733+
entity_id,
734+
Component::id,
735+
std::forward<AssocFields>(assoc_fields)...
736+
);
677737
}
678738

679739
ECSACT_ALWAYS_INLINE auto count_entities() const -> int32_t {

ecsact/runtime/dynamic.h

+20-4
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,15 @@ ECSACT_DYNAMIC_API_FN(void, ecsact_system_execution_context_add)
5757
*
5858
* Only available if has one of these capabilities:
5959
* - `ECSACT_SYS_CAP_REMOVES`
60+
*
61+
* @param ... if the component has indexed fields then those fields must be
62+
* supplied to the variadic arguments in declaration order.
6063
*/
6164
ECSACT_DYNAMIC_API_FN(void, ecsact_system_execution_context_remove)
6265
( //
6366
struct ecsact_system_execution_context* context,
64-
ecsact_component_like_id component_id
67+
ecsact_component_like_id component_id,
68+
...
6569
);
6670

6771
/**
@@ -76,12 +80,16 @@ ECSACT_DYNAMIC_API_FN(void, ecsact_system_execution_context_remove)
7680
* - `ECSACT_SYS_CAP_READWRITE`
7781
* - `ECSACT_SYS_CAP_OPTIONAL_READONLY`
7882
* - `ECSACT_SYS_CAP_OPTIONAL_READWRITE`
83+
*
84+
* @param ... if the component has indexed fields then those fields must be
85+
* supplied to the variadic arguments in declaration order.
7986
*/
8087
ECSACT_DYNAMIC_API_FN(void, ecsact_system_execution_context_get)
8188
( //
8289
struct ecsact_system_execution_context* context,
8390
ecsact_component_like_id component_id,
84-
void* out_component_data
91+
void* out_component_data,
92+
...
8593
);
8694

8795
/**
@@ -90,12 +98,16 @@ ECSACT_DYNAMIC_API_FN(void, ecsact_system_execution_context_get)
9098
* - `ECSACT_SYS_CAP_READWRITE`
9199
* - `ECSACT_SYS_CAP_OPTIONAL_WRITEONLY`
92100
* - `ECSACT_SYS_CAP_OPTIONAL_READWRITE`
101+
*
102+
* @param ... if the component has indexed fields then those fields must be
103+
* supplied to the variadic arguments in declaration order.
93104
*/
94105
ECSACT_DYNAMIC_API_FN(void, ecsact_system_execution_context_update)
95106
( //
96107
struct ecsact_system_execution_context* context,
97108
ecsact_component_like_id component_id,
98-
const void* component_data
109+
const void* component_data,
110+
...
99111
);
100112

101113
/**
@@ -106,11 +118,15 @@ ECSACT_DYNAMIC_API_FN(void, ecsact_system_execution_context_update)
106118
* - `ECSACT_SYS_CAP_OPTIONAL_READONLY`
107119
* - `ECSACT_SYS_CAP_OPTIONAL_WRITEONLY`
108120
* - `ECSACT_SYS_CAP_OPTIONAL_READWRITE`
121+
*
122+
* @param ... if the component has indexed fields then those fields must be
123+
* supplied to the variadic arguments in declaration order.
109124
*/
110125
ECSACT_DYNAMIC_API_FN(bool, ecsact_system_execution_context_has)
111126
( //
112127
struct ecsact_system_execution_context* context,
113-
ecsact_component_like_id component_id
128+
ecsact_component_like_id component_id,
129+
...
114130
);
115131

116132
/**

0 commit comments

Comments
 (0)