entity: add ENT_ARRAY_ADD_FIRSTFREE(array, ent)

Like ENT_ARRAY_ADD, but tries to scan the array for dead slots first. If
it finds one, it will put the new entity into that slot instead of
adding a new one. Returns the index. The regular ENT_ARRAY_ADD() now
also returns the index as well.
This commit is contained in:
Andrei Alexeyev 2024-04-11 17:35:46 +02:00
parent 863468db1a
commit 1b95645754
No known key found for this signature in database
GPG key ID: 72D26128040B9690
2 changed files with 39 additions and 13 deletions

View file

@ -238,3 +238,14 @@ void _ent_array_compact_Entity(BoxedEntityArray *a) {
}
}
}
int _ent_array_add_firstfree_BoxedEntity(BoxedEntity box, BoxedEntityArray *a) {
for(int i = 0; i < a->size; ++i) {
if(!ENT_UNBOX(a->array[i])) {
a->array[i] = box;
return i;
}
}
return _ent_array_add_BoxedEntity(box, a);
}

View file

@ -242,9 +242,11 @@ typedef struct BoxedEntityArray {
uint size; \
}; \
} Boxed##typename##Array; \
INLINE void _ent_array_add_##typename(Boxed##typename box, Boxed##typename##Array *a) { \
assert(a->size < a->capacity); \
a->array[a->size++] = box; \
INLINE int _ent_array_add_##typename(Boxed##typename box, Boxed##typename##Array *a) { \
return _ent_array_add_BoxedEntity(box.as_generic, &a->as_generic_UNSAFE); \
} \
INLINE int _ent_array_add_firstfree_##typename(Boxed##typename box, Boxed##typename##Array *a) { \
return _ent_array_add_firstfree_BoxedEntity(box.as_generic, &a->as_generic_UNSAFE); \
} \
INLINE void _ent_array_compact_##typename(Boxed##typename##Array *a) { \
_ent_array_compact_Entity(&a->as_generic_UNSAFE); \
@ -252,19 +254,32 @@ typedef struct BoxedEntityArray {
void _ent_array_compact_Entity(BoxedEntityArray *a);
INLINE int _ent_array_add_BoxedEntity(BoxedEntity box, BoxedEntityArray *a) {
assert(a->size < a->capacity);
int i = a->size++;
a->array[i] = box;
return i;
}
INLINE int _ent_array_add_Entity(struct EntityInterface *ent, BoxedEntityArray *a) {
return _ent_array_add_BoxedEntity(ENT_BOX(ent), a);
}
int _ent_array_add_firstfree_BoxedEntity(BoxedEntity box, BoxedEntityArray *a);
INLINE int _ent_array_add_firstfree_Entity(
struct EntityInterface *ent, BoxedEntityArray *a
) {
return _ent_array_add_firstfree_BoxedEntity(ENT_BOX(ent), a);
}
ENTITIES(ENT_EMIT_ARRAY_DEFS,)
#undef ENT_EMIT_ARRAY_DEFS
INLINE void _ent_array_add_BoxedEntity(BoxedEntity box, BoxedEntityArray *a) {
assert(a->size < a->capacity);
a->array[a->size++] = box;
}
INLINE void _ent_array_add_Entity(struct EntityInterface *ent, BoxedEntityArray *a) {
_ent_array_add_BoxedEntity(ENT_BOX(ent), a);
}
#define ENT_ARRAY_ADD(_array, _ent) ENT_BOXED_DISPATCH_FUNCTION(_ent_array_add_, ENT_BOX_OR_PASSTHROUGH(_ent), _array)
#define ENT_ARRAY_ADD(_array, _ent) \
ENT_BOXED_DISPATCH_FUNCTION(_ent_array_add_, ENT_BOX_OR_PASSTHROUGH(_ent), _array)
#define ENT_ARRAY_ADD_FIRSTFREE(_array, _ent) \
ENT_BOXED_DISPATCH_FUNCTION(_ent_array_add_firstfree_, ENT_BOX_OR_PASSTHROUGH(_ent), _array)
#define ENT_ARRAY_GET_BOXED(_array, _index) ((_array)->array[_index])
#define ENT_ARRAY_GET(_array, _index) ENT_UNBOX(ENT_ARRAY_GET_BOXED(_array, _index))
#define ENT_ARRAY_COMPACT(_array) \