Move flecs out of engine, reorganize systems

This commit is contained in:
2023-11-17 20:29:51 +01:00
parent 2167d10501
commit 5cbb7b6c94
7 changed files with 130 additions and 157 deletions

View File

@@ -20,22 +20,14 @@ typedef struct BzAppDesc {
BzAppRenderFunc imguiRender;
BzAppDeinitFunc deinit;
bool useFlecs;
void *userData;
} BzAppDesc;
typedef struct ecs_world_t ecs_world_t;
extern ecs_world_t *ECS;
extern bool bzMain(BzAppDesc *appDesc, int argc, const char **argv);
#ifdef BZ_ENTRYPOINT
#include <flecs.h>
#include <rlImGui.h>
ecs_world_t *ECS = NULL;
// https://www.raylib.com/examples/core/loader.html?name=core_custom_logging
static void bzRaylibLogger(int msgType, const char *text, va_list args) {
BzLoggerLevel level = BZ_LOG_TRACE;
@@ -94,8 +86,6 @@ int main(int argc, const char **argv) {
SetTargetFPS(appDesc.fps);
// Initialize modules
if (appDesc.useFlecs)
ECS = ecs_init();
if (appDesc.imguiRender)
rlImGuiSetup(true);
@@ -131,10 +121,6 @@ int main(int argc, const char **argv) {
// Deinitialize modules
if (appDesc.imguiRender)
rlImGuiShutdown();
if (ECS) {
ecs_fini(ECS);
ECS = NULL;
}
CloseWindow();
bzLoggerDeinit();

View File

@@ -4,17 +4,21 @@ ECS_TAG_DECLARE(TextureTerrain);
ECS_TAG_DECLARE(TextureBuildings);
ECS_TAG_DECLARE(TextureEntities);
ECS_COMPONENT_DECLARE(Resource);
ECS_COMPONENT_DECLARE(TilePosition);
ECS_COMPONENT_DECLARE(TileSize);
ECS_COMPONENT_DECLARE(Owner);
ECS_COMPONENT_DECLARE(SpatialGridID);
ECS_COMPONENT_DECLARE(Position);
ECS_COMPONENT_DECLARE(Size);
ECS_COMPONENT_DECLARE(TargetPosition);
ECS_COMPONENT_DECLARE(MoveForce);
ECS_COMPONENT_DECLARE(Resource);
ECS_COMPONENT_DECLARE(SpatialGridID);
ECS_COMPONENT_DECLARE(Velocity);
ECS_COMPONENT_DECLARE(Rotation);
ECS_COMPONENT_DECLARE(Health);
ECS_COMPONENT_DECLARE(AngularVelocity);
ECS_COMPONENT_DECLARE(SteeringOutput);
ECS_COMPONENT_DECLARE(TextureRegion);
ECS_COMPONENT_DECLARE(AnimationType);
ECS_COMPONENT_DECLARE(Animation);
@@ -25,17 +29,21 @@ void initComponentIDs(ecs_world_t *ecs) {
ECS_TAG_DEFINE(ecs, TextureBuildings);
ECS_TAG_DEFINE(ecs, TextureEntities);
ECS_COMPONENT_DEFINE(ecs, Resource);
ECS_COMPONENT_DEFINE(ecs, TilePosition);
ECS_COMPONENT_DEFINE(ecs, TileSize);
ECS_COMPONENT_DEFINE(ecs, Owner);
ECS_COMPONENT_DEFINE(ecs, SpatialGridID);
ECS_COMPONENT_DEFINE(ecs, Position);
ECS_COMPONENT_DEFINE(ecs, Size);
ECS_COMPONENT_DEFINE(ecs, TargetPosition);
ECS_COMPONENT_DEFINE(ecs, MoveForce);
ECS_COMPONENT_DEFINE(ecs, Resource);
ECS_COMPONENT_DEFINE(ecs, SpatialGridID);
ECS_COMPONENT_DEFINE(ecs, Velocity);
ECS_COMPONENT_DEFINE(ecs, Rotation);
ECS_COMPONENT_DEFINE(ecs, Health);
ECS_COMPONENT_DEFINE(ecs, AngularVelocity);
ECS_COMPONENT_DEFINE(ecs, SteeringOutput);
ECS_COMPONENT_DEFINE(ecs, TextureRegion);
ECS_COMPONENT_DEFINE(ecs, AnimationType);
ECS_COMPONENT_DEFINE(ecs, Animation);

View File

@@ -10,6 +10,20 @@ extern ECS_TAG_DECLARE(TextureTerrain);
extern ECS_TAG_DECLARE(TextureBuildings);
extern ECS_TAG_DECLARE(TextureEntities);
typedef enum ResourceType {
RES_IRON,
RES_WOOD,
RES_GOLD,
RES_FOOD,
RES_COUNT,
} ResourceType;
typedef struct Resource {
ResourceType type;
i32 amount;
} Resource;
extern ECS_COMPONENT_DECLARE(Resource);
typedef struct TilePosition {
BzTile x;
BzTile y;
@@ -27,34 +41,21 @@ typedef struct Owner {
} Owner;
extern ECS_COMPONENT_DECLARE(Owner);
typedef Vector2 Position, Size, TargetPosition, MoveForce;
extern ECS_COMPONENT_DECLARE(Position);
extern ECS_COMPONENT_DECLARE(Size);
extern ECS_COMPONENT_DECLARE(TargetPosition);
extern ECS_COMPONENT_DECLARE(MoveForce);
typedef enum ResourceType {
RES_IRON,
RES_WOOD,
RES_GOLD,
RES_FOOD,
RES_COUNT,
} ResourceType;
typedef struct Resource {
ResourceType type;
i32 amount;
} Resource;
extern ECS_COMPONENT_DECLARE(Resource);
typedef BzSpatialGridID SpatialGridID;
extern ECS_COMPONENT_DECLARE(SpatialGridID);
typedef f32 Rotation;
typedef Vector2 Position, Size, Velocity;
extern ECS_COMPONENT_DECLARE(Position);
extern ECS_COMPONENT_DECLARE(Size);
extern ECS_COMPONENT_DECLARE(Velocity);
typedef f32 Rotation, AngularVelocity;
extern ECS_COMPONENT_DECLARE(Rotation);
typedef f32 Health;
extern ECS_COMPONENT_DECLARE(Health);
extern ECS_COMPONENT_DECLARE(AngularVelocity);
typedef struct SteeringOutput {
Vector2 linear;
f32 angular;
} SteeringOutput;
extern ECS_COMPONENT_DECLARE(SteeringOutput);
typedef struct TextureRegion {
Texture2D texture;

View File

@@ -43,6 +43,8 @@ typedef struct Game {
f32 elapsed;
} Game;
extern ecs_world_t *ECS;
extern ECS_COMPONENT_DECLARE(Game);
#endif //PIXELDEFENSE_GAME_STATE_H

View File

@@ -12,6 +12,8 @@
ECS_COMPONENT_DECLARE(Game);
ecs_world_t *ECS = NULL;
bool init(void *userData);
void deinit(void *userData);
@@ -33,14 +35,15 @@ bool bzMain(BzAppDesc *appDesc, int argc, const char **argv) {
appDesc->imguiRender = (BzAppRenderFunc) imguiRender;
appDesc->userData = NULL;
appDesc->useFlecs = true;
return true;
}
bool init(void *userData) {
BZ_UNUSED(userData);
SetExitKey(-1);
SetExitKey(KEY_ESCAPE);
ECS = ecs_init();
ECS_COMPONENT_DEFINE(ECS, Game);
initComponentIDs(ECS);
@@ -114,12 +117,10 @@ bool init(void *userData) {
bzTileMapOverrideObjectGroup(&game->map, OBJECTS_GAME, initGameObjectsLayer);
bzTileMapOverrideObjectGroup(&game->map, OBJECTS_ENTITIES, initEntityObjectsLayer);
ECS_SYSTEM(ECS, uiTask, EcsOnUpdate, 0);
ECS_SYSTEM(ECS, updateAnimations, EcsOnUpdate, Animation, TextureRegion);
ECS_SYSTEM(ECS, updatePos, EcsOnUpdate, Position, TargetPosition, TextureRegion);
ECS_SYSTEM(ECS, entityUpdatePhysics, EcsOnUpdate, Position, Size, SpatialGridID);
ECS_OBSERVER(ECS, entitySpatialRemoved, EcsOnRemove, Position, SpatialGridID);
ECS_OBSERVER(ECS, pathRemoved, EcsOnRemove, Path);
ECS_SYSTEM(ECS, drawDebugPath, EcsOnUpdate, Path);
ECS_SYSTEM(ECS, renderDebugPath, EcsOnUpdate, Path);
ECS_SYSTEM(ECS, renderTerrain, EcsOnUpdate, Position, Size, Rotation, TextureRegion, TextureTerrain);
ECS_SYSTEM(ECS, renderBuildings, EcsOnUpdate, Position, Size, Rotation, TextureRegion, TextureBuildings);
@@ -127,8 +128,6 @@ bool init(void *userData) {
ECS_SYSTEM(ECS, renderColliders, EcsOnUpdate, Position, Size);
ECS_OBSERVER(ECS, targetFinish, EcsOnRemove, TargetPosition);
ECS_OBSERVER(ECS, startPath, EcsOnSet, Path);
return true;
}
void deinit(void *userData) {
@@ -140,11 +139,11 @@ void deinit(void *userData) {
bzTilesetDestroy(&game->buildingsTileset);
bzTilesetDestroy(&game->entitiesTileset);
ecs_fini(ECS);
ECS = NULL;
bzObjectPoolDestroy(game->pools.pathData);
bzSpatialGridDestroy(game->entityGrid);
ecs_singleton_remove(ECS, Game);
}

View File

@@ -10,23 +10,39 @@
* Entity Systems
**********************************/
/*
* 0: Game (singleton)
*/
void entityRemoved(ecs_iter_t *it);
/*
* 0: Game (singleton)
*/
void entityAdded(ecs_iter_t *it);
/*
/* Observer (for unregistering collision)
* 0: Game (singleton)
* 1: Position
* 2: Size
* 3: MoveForce
* 4: SpatialGridID
* 3: SpatialGridID
*/
void entityUpdatePhysics(ecs_iter_t *it);
void entitySpatialRemoved(ecs_iter_t *it);
/* Observer (for releasing path objects)
* 0: Game (singleton)l for object pool
* 1: Path
*/
void pathRemoved(ecs_iter_t *it);
/*
* 0: Game (singleton) for collisions
* 1: Position
* 2: Rotation
* 3: Velocity
* 4: AngularVelocity
* 5: SteeringOutput
*/
void entityUpdateKinematic(ecs_iter_t *it);
/*
* 1: Position
* 2: Rotation
* 3: Velocity
* 4: AngularVelocity
* 5: SteeringOutput
* 6: Path
*/
void entityFollowPath(ecs_iter_t *it);
/*
* 0:
@@ -41,13 +57,9 @@ void renderEntities(ecs_iter_t *it);
*/
void renderColliders(ecs_iter_t *it);
//void renderEntities(ecs_iter_t *it);
void updateAnimations(ecs_iter_t *it);
void updatePos(ecs_iter_t *it);
void targetFinish(ecs_iter_t *it);
void startPath(ecs_iter_t *it);
void drawDebugPath(ecs_iter_t *it);
void uiTask(ecs_iter_t *it);
/*
* 1: Path
*/
void renderDebugPath(ecs_iter_t *it);
#endif //PIXELDEFENSE_SYSTEMS_H

View File

@@ -5,30 +5,53 @@
#include <math.h>
#include <raymath.h>
void entityRemoved(ecs_iter_t *it) {
static Position getBottomLeftPos(Position pos, Size size) {
return (Position) {pos.x - size.x * 0.5f, pos.y - size.y * 0.5f};
}
void entityAdded(ecs_iter_t *it) {
}
void entityUpdatePhysics(ecs_iter_t *it) {
void entitySpatialRemoved(ecs_iter_t *it) {
Game *game = ecs_singleton_get_mut(ECS, Game);
Position *pos = ecs_field(it, Position, 1);
Size *size = ecs_field(it, Size, 2);
//MoveForce *force = ecs_field(it, MoveForce, 3);
SpatialGridID *spatialID = ecs_field(it, SpatialGridID, 3);
SpatialGridID *spatialID = ecs_field(it, SpatialGridID , 2);
for (i32 i = 0; i < it->count; i++) {
//bzSpatialGridUpdate(game->entityGrid, spatialID[i], pos[i].x, pos[i].y, size[i].x, size[i].y);
ecs_entity_t *e = bzSpatialGridGetData(game->entityGrid, spatialID[i]);
BZ_ASSERT(*e == it->entities[i]);
f32 posX = pos[i].x - size[i].x * 0.5f;
f32 posY = pos[i].y - size[i].y * 0.5f;
bzSpatialGridUpdate(game->entityGrid, spatialID[i], posX, posY, size[i].x, size[i].y);
bzSpatialGridRemove(game->entityGrid, spatialID[i]);
}
}
void pathRemoved(ecs_iter_t *it) {
Game *game = ecs_singleton_get_mut(ECS, Game);
BzObjectPool *pool = game->pools.pathData;
Path *path = ecs_field(it, Path, 1);
for (i32 i = 0; i < it->count; i++) {
PathData *cur = path[i].paths;
while (cur) {
bzObjectPoolRelease(pool, cur);
cur = cur->next;
}
}
}
void entityUpdateKinematic(ecs_iter_t *it) {
Position *pos = ecs_field(it, Position, 1);
Rotation *rotation = ecs_field(it, Rotation, 2);
Velocity *velocity = ecs_field(it, Velocity, 3);
AngularVelocity *angularVelocity = ecs_field(it, Rotation, 4);
SteeringOutput *steeringOutput = ecs_field(it, SteeringOutput, 5);
}
void entityFollowPath(ecs_iter_t *it) {
Position *pos = ecs_field(it, Position, 1);
Rotation *rotation = ecs_field(it, Rotation, 2);
Velocity *velocity = ecs_field(it, Velocity, 3);
AngularVelocity *angularVelocity = ecs_field(it, Rotation, 4);
SteeringOutput *steeringOutput = ecs_field(it, SteeringOutput, 5);
Path *path = ecs_field(it, Path, 6);
}
void updateAnimations(ecs_iter_t *it) {
Game *game = ecs_singleton_get_mut(ECS, Game);
Animation *anim = ecs_field(it, Animation, 1);
@@ -66,9 +89,11 @@ static void render(ecs_iter_t *it) {
void renderTerrain(ecs_iter_t *it) {
render(it);
}
void renderBuildings(ecs_iter_t *it) {
render(it);
}
void renderEntities(ecs_iter_t *it) {
render(it);
}
@@ -84,68 +109,8 @@ void renderColliders(ecs_iter_t *it) {
}
}
void updatePos(ecs_iter_t *it) {
Position *pos = ecs_field(it, Position, 1);
TargetPosition *target = ecs_field(it, TargetPosition, 2);
TextureRegion *t = ecs_field(it, TextureRegion, 3);
for (i32 i = 0; i < it->count; i++) {
Vector2 d = Vector2Subtract(target[i], pos[i]);
if (Vector2LengthSqr(d) < 1) {
ecs_remove(ECS, it->entities[i], TargetPosition);
}
Vector2 dN = Vector2Normalize(d);
dN = Vector2Scale(dN, 20);
t[i].flipX = dN.x < 0;
pos[i].x += dN.x * it->delta_time;
pos[i].y += dN.y * it->delta_time;
}
}
#include <stdlib.h>
void targetFinish(ecs_iter_t *it) {
const Game *game = ecs_singleton_get(ECS, Game);
if (game == NULL) return;
for (i32 i = 0; i < it->count; i++) {
ecs_entity_t e = it->entities[i];
Path *path = ecs_get_mut(it->world, e, Path);
if (path->curWaypoint >= path->paths->numWaypoints) {
PathData *finished = path->paths;
path->paths = finished->next;
path->curWaypoint = 0;
bzObjectPoolRelease(game->pools.pathData, finished);
// Finished
if (path->paths == NULL) {
ecs_remove(it->world, e, Path);
continue;
}
}
TargetPosition target = path->paths->waypoints[path->curWaypoint];
path->curWaypoint++;
target.x += rand() % (4 + 1 + 2) -2;
ecs_set(it->world, e, TargetPosition, {target.x, target.y});
}
}
void startPath(ecs_iter_t *it) {
Path *path = ecs_field(it, Path, 1);
for (i32 i = 0; i < it->count; i++) {
ecs_entity_t e = it->entities[i];
if (path->paths == NULL) {
ecs_remove(it->world, e, Path);
continue;
}
ecs_set(it->world, e, TargetPosition, {path[i].paths->waypoints[0].x, path[i].paths->waypoints[0].y});
path[i].curWaypoint = 1;
}
}
void drawDebugPath(ecs_iter_t *it) {
void renderDebugPath(ecs_iter_t *it) {
Path *path = ecs_field(it, Path, 1);
for (i32 i = 0; i < it->count; i++) {