Fix flocking bug

This commit is contained in:
2026-05-26 20:24:34 -05:00
parent 109318aeaf
commit 7c4b8c307f
10 changed files with 76 additions and 25 deletions
+3
View File
@@ -16,6 +16,9 @@ else()
)
endif()
# Export symbols so backtrace_symbols() can resolve function names.
target_link_options(${DUSK_LIBRARY_TARGET_NAME} PUBLIC -rdynamic)
# Link required libraries.
target_link_libraries(${DUSK_LIBRARY_TARGET_NAME} PUBLIC
SDL2
+22 -1
View File
@@ -9,6 +9,24 @@
#include "log/log.h"
#include "util/string.h"
#ifdef DUSK_LINUX
#include <execinfo.h>
#include <stdlib.h>
static void assertLogBacktrace(void) {
void *frames[64];
int count = backtrace(frames, 64);
char **symbols = backtrace_symbols(frames, count);
logError("Stack trace:\n");
if(symbols) {
for(int i = 0; i < count; i++) {
logError(" %s\n", symbols[i]);
}
free(symbols);
}
}
#endif
#ifndef DUSK_ASSERTIONS_FAKED
#ifdef DUSK_TEST_ASSERT
void assertTrueImpl(
@@ -33,11 +51,14 @@
) {
if(x != true) {
logError(
"Assertion Failed in %s:%i\n\n%s\n",
"Assertion Failed in %s:%i\n\n%s\n\n",
file,
line,
message
);
#ifdef DUSK_LINUX
assertLogBacktrace();
#endif
abort();
}
}
+16 -2
View File
@@ -12,12 +12,13 @@
componentdefinition_t COMPONENT_DEFINITIONS[] = {
[COMPONENT_TYPE_NULL] = { 0 },
#define X(enm, type, field, iMethod, dMethod) \
#define X(enm, type, field, iMethod, dMethod, rMethod) \
[COMPONENT_TYPE_##enm] = { \
.enumName = #enm, \
.name = #field, \
.init = iMethod, \
.dispose = dMethod \
.dispose = dMethod, \
.render = rMethod \
},
#include "componentlist.h"
@@ -114,6 +115,19 @@ entityid_t componentGetEntitiesWithComponent(
return written;
}
errorret_t componentRenderAll(void) {
for(entityid_t eid = 0; eid < ENTITY_COUNT_MAX; eid++) {
if(!(ENTITY_MANAGER.entities[eid].state & ENTITY_STATE_ACTIVE)) continue;
for(componentid_t cid = 0; cid < ENTITY_COMPONENT_COUNT_MAX; cid++) {
component_t *cmp = &ENTITY_MANAGER.components[componentGetIndex(eid, cid)];
if(cmp->type == COMPONENT_TYPE_NULL) continue;
if(!COMPONENT_DEFINITIONS[cmp->type].render) continue;
errorChain(COMPONENT_DEFINITIONS[cmp->type].render(eid, cid));
}
}
errorOk();
}
void componentDispose(
const entityid_t entityId,
const componentid_t componentId
+15 -5
View File
@@ -8,13 +8,13 @@
#pragma once
#include "entitybase.h"
#define X(enumName, type, field, init, dispose) \
#define X(enumName, type, field, init, dispose, render) \
// do nothing
#include "componentlist.h"
#undef X
typedef union {
#define X(enumName, type, field, init, dispose) type field;
#define X(enumName, type, field, init, dispose, render) type field;
#include "componentlist.h"
#undef X
} componentdata_t;
@@ -24,12 +24,13 @@ typedef struct {
const char_t *name;
void (*init)(const entityid_t, const componentid_t);
void (*dispose)(const entityid_t, const componentid_t);
errorret_t (*render)(const entityid_t, const componentid_t);
} componentdefinition_t;
typedef enum {
COMPONENT_TYPE_NULL,
#define X(enumName, type, field, init, dispose) \
#define X(enumName, type, field, init, dispose, render) \
COMPONENT_TYPE_##enumName,
#include "componentlist.h"
#undef X
@@ -100,11 +101,20 @@ entityid_t componentGetEntitiesWithComponent(
/**
* Disposes of a component for the entity with component ID.
*
*
* @param entityId The entity ID.
* @param componentId The component ID.
*/
void componentDispose(
const entityid_t entityId,
const componentid_t componentId
);
);
/**
* Calls the render callback on every active component that defines one.
* Iterates all active entities and all their component slots. No-op for
* components whose definition has render == NULL.
*
* @return Error state.
*/
errorret_t componentRenderAll(void);
@@ -40,7 +40,7 @@ void entityOverworldCameraSetTarget(
cam->targetPosCompId = targetPosCompId;
}
void entityOverworldCameraUpdate(
errorret_t entityOverworldCameraRender(
const entityid_t entityId,
const componentid_t componentId
) {
@@ -62,4 +62,5 @@ void entityOverworldCameraUpdate(
entityCameraLookAtPixelPerfect(
entityId, posComp, camComp, center, cam->eyeOffset, cam->scale
);
errorOk();
}
@@ -7,6 +7,7 @@
#pragma once
#include "entity/entitybase.h"
#include "error/error.h"
typedef struct {
entityid_t targetEntityId;
@@ -55,12 +56,14 @@ void entityOverworldCameraSetTarget(
);
/**
* Updates the camera position to track the target entity.
* Render callback: updates the camera position to track the target entity.
* Called automatically each frame via componentRenderAll.
*
* @param entityId The owning entity.
* @param componentId This component's ID.
* @return Error state.
*/
void entityOverworldCameraUpdate(
errorret_t entityOverworldCameraRender(
const entityid_t entityId,
const componentid_t componentId
);
+10 -9
View File
@@ -20,13 +20,14 @@
// Field name (lowercase)
// Init function (optional)
// Dispose function (optional)
// Render function (optional)
X(POSITION, entityposition_t, position, entityPositionInit, NULL)
X(CAMERA, entitycamera_t, camera, entityCameraInit, NULL)
X(RENDERABLE, entityrenderable_t, renderable, entityRenderableInit, entityRenderableDispose)
X(PHYSICS, entityphysics_t, physics, entityPhysicsInit, entityPhysicsDispose)
X(TRIGGER, entitytrigger_t, trigger, entityTriggerInit, NULL)
X(OVERWORLD, entityoverworld_t, overworld, entityOverworldInit, NULL)
X(PLAYER, entityplayer_t, player, entityPlayerInit, NULL)
X(INTERACTABLE, entityinteractable_t, interactable, entityInteractableInit, NULL)
X(OVERWORLD_CAMERA, entityoverworldcamera_t, overworldCamera, entityOverworldCameraInit, NULL)
X(POSITION, entityposition_t, position, entityPositionInit, NULL, NULL)
X(CAMERA, entitycamera_t, camera, entityCameraInit, NULL, NULL)
X(RENDERABLE, entityrenderable_t, renderable, entityRenderableInit, entityRenderableDispose, NULL)
X(PHYSICS, entityphysics_t, physics, entityPhysicsInit, entityPhysicsDispose, NULL)
X(TRIGGER, entitytrigger_t, trigger, entityTriggerInit, NULL, NULL)
X(OVERWORLD, entityoverworld_t, overworld, entityOverworldInit, NULL, NULL)
X(PLAYER, entityplayer_t, player, entityPlayerInit, NULL, NULL)
X(INTERACTABLE, entityinteractable_t, interactable, entityInteractableInit, NULL, NULL)
X(OVERWORLD_CAMERA, entityoverworldcamera_t, overworldCamera, entityOverworldCameraInit, NULL, entityOverworldCameraRender)
@@ -16,6 +16,7 @@ void overworldGroundAdd(overworldground_t *ground) {
ground->posCompId = entityAddComponent(
ground->entityId, COMPONENT_TYPE_POSITION
);
entityAddComponent(ground->entityId, COMPONENT_TYPE_RENDERABLE);
vec3 pos = { -OVERWORLD_GROUND_SIZE, 0.0f, -OVERWORLD_GROUND_SIZE };
vec3 scale = { OVERWORLD_GROUND_SIZE * 2.0f, 1.0f, OVERWORLD_GROUND_SIZE * 2.0f };
entityPositionSetLocalPosition(ground->entityId, ground->posCompId, pos);
@@ -122,11 +122,6 @@ void overworldSceneInit(void) {
errorret_t overworldSceneUpdate(void) {
overworldPlayerUpdate(&OVERWORLD.player);
entityOverworldCameraUpdate(
OVERWORLD.cameraEntityId, OVERWORLD.cameraOverworldCompId
);
errorOk();
}
+2
View File
@@ -16,6 +16,7 @@
#include "util/string.h"
#include "ui/ui.h"
#include "scene/scenerenderpipeline.h"
#include "entity/component.h"
scenefuncs_t SCENE_FUNCTIONS[SCENE_TYPE_COUNT] = {
{ 0 },
@@ -71,6 +72,7 @@ errorret_t sceneRender(void) {
mat4 proj, view, ident;
glm_mat4_identity(ident);
errorChain(componentRenderAll());
errorChain(sceneRenderPipeline(entityCameraGetCurrent()));
// UI Rendering