move boid-list to separate file

This commit is contained in:
Rokas Puzonas 2023-07-20 23:27:49 +03:00
parent 7e1bb9daec
commit 189be11d10
5 changed files with 107 additions and 144 deletions

View File

@ -8,13 +8,13 @@ TOP_BUILD_DIR := build
EXECUTABLE := boids-playground
SUBMODULES_PATH := depends
# default stack - 65536
# 67108864 = 64MiB
WEB_HEAP_SIZE := 1105199104
WEB_STACK_SIZE := 262144
# WEB_HEAP_SIZE default: 16777216 (16MiB)
WEB_HEAP_SIZE := 335544320
# WEB_STACK_SIZE default: 65536 (64KiB)
WEB_STACK_SIZE := 196608
WEB_SHELL := src/shell.html
COMPILER_FLAGS := -std=c++17 -Wno-enum-compare -s -O1
COMPILER_FLAGS := -std=c++17 -Wno-enum-compare -O2
LINKER_FLAGS := -lraylib
# SOURCES := $(wildcard src/*.cpp)

67
src/boid-list.cpp Normal file
View File

@ -0,0 +1,67 @@
#include <algorithm>
#include "boid-list.hpp"
static BoidsListNodeIterator boid_list_get_iterator(BoidsListNode *node, uint16_t count) {
return { .node = node, .i = 0, .count = count };
}
static bool boid_list_iterator_next(BoidsListNodeIterator *iterator, uint16_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;
}
static void boid_list_append(MemoryArena *arena, BoidsListNode *node, uint16_t *count, uint16_t new_boid) {
int left_count = *count;
BoidsListNode *prev = node;
BoidsListNode *curr = node;
while (left_count > BOIDS_PER_NODE && curr) {
prev = curr;
curr = curr->next;
left_count -= BOIDS_PER_NODE;
}
if (curr == NULL) {
curr = (BoidsListNode*)arena_malloc(arena, sizeof(BoidsListNode));
curr->next = NULL;
prev->next = curr;
}
prev->boid_ids[left_count] = new_boid;
(*count)++;
}
static void boid_list_append_unique(MemoryArena *arena, BoidsListNode *local_boids, uint16_t *count, uint16_t new_boid) {
int left_count = *count;
BoidsListNode *last = local_boids;
BoidsListNode *curr = local_boids;
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 = (*count) % BOIDS_PER_NODE;
if (idx == BOIDS_PER_NODE-1) {
last->next = (BoidsListNode*)arena_malloc(arena, sizeof(BoidsListNode));
last->next->next = NULL;
}
last->boid_ids[idx] = new_boid;
(*count)++;
}

22
src/boid-list.hpp Normal file
View File

@ -0,0 +1,22 @@
#include <inttypes.h>
#include "memory-arena.hpp"
#define BOIDS_PER_NODE 32
struct BoidsListNode {
uint16_t boid_ids[BOIDS_PER_NODE];
BoidsListNode *next;
};
struct BoidsListNodeIterator {
BoidsListNode *node;
int i;
uint16_t count;
};
static BoidsListNodeIterator boid_list_get_iterator(BoidsListNode *node, uint16_t count);
static bool boid_list_iterator_next(BoidsListNodeIterator *iterator, uint16_t *value);
static void boid_list_append(MemoryArena *arena, BoidsListNode *node, uint16_t *count, uint16_t new_boid);
static void boid_list_append_unique(MemoryArena *arena, BoidsListNode *local_boids, uint16_t *count, uint16_t new_boid);

View File

@ -82,16 +82,3 @@ struct UI {
bool separation_strength_edit = false;
bool collision_avoidance_strength_edit = false;
};
#define BOIDS_PER_NODE 32
struct BoidsListNode {
uint16_t boid_ids[BOIDS_PER_NODE];
BoidsListNode *next;
};
struct BoidsListNodeIterator {
BoidsListNode *node;
int i;
uint16_t count;
};

View File

@ -12,12 +12,13 @@
#include "raygui.h"
#define RPROF_IMPLEMENTATION
// #define RPROF_ONLY_TOTAL_TIME
#define RPROF_STUB_OUT
#include "rprof.h"
#include "boid-playground.hpp"
#include "raycast.cpp"
#include "memory-arena.cpp"
#include "boid-list.cpp"
#define FRAMERATE 60
#define TIME_PER_FRAME (1.0/FRAMERATE)
@ -54,7 +55,7 @@ static void boid_rand_init(World *world, Boid *boid, float border) {
}
static void world_init(World *world, float width, float height) {
arena_init(&world->frame_arena, 1024 * 1024 * 1024);
arena_init(&world->frame_arena, 1024 * 1024 * 256);
g_world.size = { width, height };
}
@ -189,70 +190,6 @@ static void draw_circle_sector(Vector2 center, float radius, float start_angle,
rlEnd();
}
static BoidsListNodeIterator boid_list_get_iterator(BoidsListNode *node, uint16_t count) {
return { .node = node, .i = 0, .count = count };
}
static bool boid_list_iterator_next(BoidsListNodeIterator *iterator, uint16_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;
}
static void boid_list_append(MemoryArena *arena, BoidsListNode *node, uint16_t *count, uint16_t new_boid) {
int left_count = *count;
BoidsListNode *prev = node;
BoidsListNode *curr = node;
while (left_count > BOIDS_PER_NODE && curr) {
prev = curr;
curr = curr->next;
left_count -= BOIDS_PER_NODE;
}
if (curr == NULL) {
curr = (BoidsListNode*)arena_malloc(arena, sizeof(BoidsListNode));
curr->next = NULL;
prev->next = curr;
}
prev->boid_ids[left_count] = new_boid;
(*count)++;
}
static void boid_list_append_unique(MemoryArena *arena, BoidsListNode *local_boids, uint16_t *count, uint16_t new_boid) {
int left_count = *count;
BoidsListNode *last = local_boids;
BoidsListNode *curr = local_boids;
while (left_count > 0 && curr) {
for (int i = 0; i < 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 = (*count) % BOIDS_PER_NODE;
if (idx == BOIDS_PER_NODE-1) {
last->next = (BoidsListNode*)arena_malloc(arena, sizeof(BoidsListNode));
last->next->next = NULL;
}
last->boid_ids[idx] = new_boid;
(*count)++;
}
static void assign_local_boids(World *world, BoidsListNode *local_boids, uint16_t *local_boid_counts, Boid *boids, uint16_t boid1, uint16_t boid2) {
// Simplified from: float dot_threshold = Vector2DotProduct(dir, Vector2Rotate(dir, world->view_angle/2));
float dot_threshold = cosf(world->view_angle/2);
@ -626,61 +563,13 @@ void UpdateDrawFrame() {
EndDrawing();
}
int estimate_maximum_boid_count(World *world) {
int boid_count = 1000;
int prev_boid_count = 0;
uint64_t cpu_hz = rprof_get_cpu_timer_hz(100);
do {
world->boids.clear();
for (int i = 0; i < boid_count; i++) {
Boid boid;
boid_rand_init(&g_world, &boid, 0);
g_world.boids.push_back(boid);
}
uint64_t best_duration = UINT64_MAX;
for (int i = 0; i < 20; i++) {
uint64_t start = rprof_read_cpu_timer();
world_update(&g_world, TIME_PER_FRAME);
uint64_t end = rprof_read_cpu_timer();
best_duration = std::min(best_duration, (end - start));
}
float duration_secs = (float)best_duration/cpu_hz;
// printf("duration: %f, err:%f", duration_secs, TIME_PER_FRAME - duration_secs);
int new_boid_count;
float diff = TIME_PER_FRAME - duration_secs;
if (diff < 0) {
if (prev_boid_count < boid_count) {
new_boid_count = (prev_boid_count + boid_count)/2;
} else {
new_boid_count = boid_count/2;
}
} else if (diff > 0) {
if (prev_boid_count > boid_count) {
new_boid_count = (prev_boid_count + boid_count)/2;
} else {
new_boid_count = boid_count*2;
}
}
prev_boid_count = boid_count;
boid_count = new_boid_count;
} while (std::abs(boid_count - prev_boid_count) > 10);
return boid_count;
}
int foo_main() {
void stress_test() {
rprof_init();
{
world_init(&g_world, 1280, 720);
float border = g_visuals.boid_edge_size;
for (int i = 0; i < 50000; i++) {
for (int i = 0; i < MAX_BOIDS; i++) {
Boid boid;
boid_rand_init(&g_world, &boid, border);
g_world.boids.push_back(boid);
@ -692,12 +581,10 @@ int foo_main() {
printf("arena: %ld (%.03fMiB)\n", g_world.frame_arena.offset, (float)g_world.frame_arena.offset / 1024 / 1024);
world_free(&g_world);
}
rprof_end();
rprof_output(NULL);
return 0;
}
int main() {