generated from rpuzonas/raylib-cpp-template
move boid-list to separate file
This commit is contained in:
parent
7e1bb9daec
commit
189be11d10
10
Makefile
10
Makefile
@ -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
67
src/boid-list.cpp
Normal 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
22
src/boid-list.hpp
Normal 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);
|
@ -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;
|
||||
};
|
||||
|
127
src/main.cpp
127
src/main.cpp
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user