Move flecs out of engine, reorganize systems
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
23
game/main.c
23
game/main.c
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
Reference in New Issue
Block a user