boids-playground/src/boid-list.cpp

84 lines
1.9 KiB
C++

#include <algorithm>
#include "boid-list.hpp"
void boid_list_init(BoidList *list)
{
list->node.next = NULL;
list->count = 0;
}
BoidsListNodeIterator boid_list_get_iterator(BoidList *list) {
return { .count = list->count, .i = 0, .node = &list->node };
}
bool boid_list_iterator_next(BoidsListNodeIterator *iterator, uboid_t *value) {
if (iterator->count == 0) {
return false;
}
if (iterator->i == BOIDS_PER_NODE) {
iterator->i = 0;
iterator->node = iterator->node->next;
}
*value = iterator->node->boid_ids[iterator->i];
iterator->i++;
iterator->count--;
return true;
}
void boid_list_append(MemoryArena *arena, BoidList *list, uboid_t new_boid) {
int left_count = list->count;
BoidListNode *prev = &list->node;
BoidListNode *curr = &list->node;
while (left_count >= BOIDS_PER_NODE && curr) {
prev = curr;
curr = curr->next;
left_count -= BOIDS_PER_NODE;
}
if (curr == NULL) {
curr = (BoidListNode*)arena_malloc(arena, sizeof(BoidListNode));
curr->next = NULL;
prev->next = curr;
}
curr->boid_ids[left_count] = new_boid;
list->count++;
}
void boid_list_append_unique(MemoryArena *arena, BoidList *list, uboid_t new_boid) {
int left_count = list->count;
BoidListNode *last = &list->node;
BoidListNode *curr = &list->node;
while (left_count > 0 && curr) {
for (int i = 0; i < std::min(left_count, BOIDS_PER_NODE); i++) {
if (curr->boid_ids[i] == new_boid) return;
}
last = curr;
curr = curr->next;
left_count -= BOIDS_PER_NODE;
}
int idx = list->count % BOIDS_PER_NODE;
if (idx == BOIDS_PER_NODE-1) {
last->next = (BoidListNode*)arena_malloc(arena, sizeof(BoidListNode));
last->next->next = NULL;
}
last->boid_ids[idx] = new_boid;
list->count++;
}
void boid_list_to_array(uboid_t *result, BoidList *list) {
int i = 0;
uboid_t boid;
BoidsListNodeIterator it = boid_list_get_iterator(list);
while (boid_list_iterator_next(&it, &boid)) {
result[i] = boid;
i++;
}
}