Separate out component memory pools definition

Changelog:
- Refactor the EC header files to put struct in more sensible locations:
    - Sprite and Particle Emitter + Configs are now assets, as they
      should be
    - Components type are now unsigned int, thus it is not sensitive to
      any component enums
    - Components enums are now pure index store. There are two sets of
      components: Basic for engine use, Extended for game-specific ones
- Component memory pools are now defined on outside of engine. Majority
  of the components will be game-specific, so it should be on the game
  to define the components and the mempools for all of them.
main
En Yi 2024-08-19 18:26:08 +08:00
parent d2af974b29
commit 056b50c431
9 changed files with 262 additions and 244 deletions

View File

@ -11,36 +11,39 @@
typedef struct EntityManager EntityManager_t;
typedef struct Entity Entity_t;
typedef enum ComponentEnum {
CBBOX_COMP_T = 0,
CTRANSFORM_COMP_T,
CTILECOORD_COMP_T,
CMOVEMENTSTATE_T,
CJUMP_COMP_T,
CPLAYERSTATE_T,
CCONTAINER_T,
CHITBOXES_T,
CHURTBOX_T,
CSPRITE_T,
CMOVEABLE_T,
CLIFETIMER_T,
CWATERRUNNER_T,
CAIRTIMER_T,
CEMITTER_T,
} ComponentEnum_t;
typedef enum AnchorPoint {
AP_TOP_LEFT,
AP_TOP_CENTER,
AP_TOP_RIGHT,
AP_MID_LEFT,
AP_MID_CENTER,
AP_MID_RIGHT,
AP_BOT_LEFT,
AP_BOT_CENTER,
AP_BOT_RIGHT,
} AnchorPoint_t;
typedef enum MovementMode {
REGULAR_MOVEMENT = 0,
KINEMATIC_MOVEMENT,
}MovementMode_t;
typedef struct _CBBox_t {
Vector2 size;
Vector2 offset;
Vector2 half_size;
bool solid;
bool fragile;
} CBBox_t;
/** Fundamental components:
// - Transform
// - BBox
// - TileCoords
**/
/** The component enums are purely a index store. Here, there are 3 basic component, that is necessary for the engine to function (mostly collisions)
* To extend the component list, define another set of enums as pure integer store and begin the enum at N_BASIC_COMPS
* These integers are also used by the component mempool as indices. Thus, the mempool must have the first 3 components as the basic components
**/
#define N_BASIC_COMPS 3
enum BasicComponentEnum {
CBBOX_COMP_T = 0,
CTRANSFORM_COMP_T,
CTILECOORD_COMP_T,
};
typedef struct _CTransform_t {
Vector2 prev_position;
@ -55,194 +58,13 @@ typedef struct _CTransform_t {
bool active;
} CTransform_t;
typedef struct _CMovementState_t {
uint8_t ground_state;
uint8_t water_state;
uint8_t x_dir;
float water_overlap;
} CMovementState_t;
// This is to store the occupying tiles
// Limits to store 4 tiles at a tile,
// Thus the size of the entity cannot be larger than the tile
typedef struct _CTileCoord_t {
unsigned int tiles[8];
unsigned int n_tiles;
} CTileCoord_t;
typedef struct _CJump_t {
int jump_speed;
uint8_t jumps;
uint8_t max_jumps;
uint8_t coyote_timer;
bool jumped;
bool jump_ready;
bool short_hop;
bool jump_released;
} CJump_t;
typedef enum PlayerState {
GROUNDED,
AIR,
} PlayerState_t;
typedef struct _CPlayerState_t {
Vector2 player_dir;
uint8_t jump_pressed;
uint8_t is_crouch;
bool ladder_state;
bool locked; // Whether to respond to inputs
} CPlayerState_t;
typedef enum ContainerItem {
CONTAINER_EMPTY,
CONTAINER_LEFT_ARROW,
CONTAINER_RIGHT_ARROW,
CONTAINER_UP_ARROW,
CONTAINER_DOWN_ARROW,
CONTAINER_COIN,
CONTAINER_BOMB,
CONTAINER_EXPLOSION,
} ContainerItem_t;
typedef enum ContainerMaterial {
WOODEN_CONTAINER,
METAL_CONTAINER,
} ContainerMaterial_t;
typedef struct _CContainer_t {
ContainerMaterial_t material;
ContainerItem_t item;
} CContainer_t;
typedef struct _CHitBoxes_t {
Rectangle boxes[2];
uint8_t n_boxes;
uint8_t atk;
bool one_hit;
} CHitBoxes_t;
typedef struct _CHurtbox_t {
Vector2 offset;
typedef struct _CBBox_t {
Vector2 size;
uint8_t def;
unsigned int damage_src;
} CHurtbox_t;
typedef struct _CLifeTimer_t {
float life_time;
} CLifeTimer_t;
typedef struct _CAirTimer_t {
float max_ftimer;
float curr_ftimer;
float decay_rate;
uint8_t max_count;
uint8_t curr_count;
} CAirTimer_t;
typedef struct _BFSTile {
int32_t to;
int32_t from;
bool reachable;
}BFSTile_t;
typedef struct _BFSTileMap {
BFSTile_t* tilemap;
int32_t width;
int32_t height;
int32_t len;
}BFSTileMap_t;
typedef enum _WaterRunnerState
{
BFS_RESET = 0,
BFS_START,
LOWEST_POINT_SEARCH,
LOWEST_POINT_MOVEMENT,
REACHABILITY_SEARCH,
SCANLINE_FILL,
FILL_COMPLETE,
}WaterRunerState_t;
typedef struct _CWaterRunner {
BFSTileMap_t bfs_tilemap;
WaterRunerState_t state;
struct sc_queue_32 bfs_queue;
bool* visited;
int32_t current_tile;
int32_t target_tile;
int32_t fill_idx;
int16_t fill_range[2];
uint8_t movement_delay;
int8_t movement_speed;
int16_t counter;
float fractional;
}CWaterRunner_t;
// Credits to bedroomcoders.co.uk for this
typedef struct Sprite {
Texture2D* texture;
Vector2 frame_size;
Vector2 origin; // TL of the frame
Vector2 anchor; // Where transformation anchors on
uint8_t frame_per_row;
int frame_count;
int speed;
char* name;
} Sprite_t;
typedef unsigned int (*sprite_transition_func_t)(Entity_t *ent); // Transition requires knowledge of the entity
typedef enum AnchorPoint {
AP_TOP_LEFT,
AP_TOP_CENTER,
AP_TOP_RIGHT,
AP_MID_LEFT,
AP_MID_CENTER,
AP_MID_RIGHT,
AP_BOT_LEFT,
AP_BOT_CENTER,
AP_BOT_RIGHT,
} AnchorPoint_t;
typedef struct _SpriteRenderInfo
{
Sprite_t* sprite;
Vector2 offset;
AnchorPoint_t src_anchor;
AnchorPoint_t dest_anchor;
} SpriteRenderInfo_t;
typedef struct _CSprite_t {
SpriteRenderInfo_t* sprites;
sprite_transition_func_t transition_func;
unsigned int current_idx;
bool flip_x;
bool flip_y;
bool pause;
int current_frame;
float fractional;
float rotation; // Degree
float rotation_speed; // Degree / s
int elapsed;
Vector2 offset;
Color colour;
} CSprite_t;
typedef struct _CMoveable_t {
uint16_t move_speed;
Vector2 prev_pos;
Vector2 target_pos;
bool gridmove;
} CMoveable_t;
typedef uint16_t EmitterHandle;
typedef struct _CEmitter_t
{
EmitterHandle handle;
Vector2 offset;
} CEmitter_t;
Vector2 half_size;
bool solid;
bool fragile;
} CBBox_t;
static inline void set_bbox(CBBox_t* p_bbox, unsigned int x, unsigned int y)
{
@ -251,6 +73,13 @@ static inline void set_bbox(CBBox_t* p_bbox, unsigned int x, unsigned int y)
p_bbox->half_size.x = (unsigned int)(x / 2);
p_bbox->half_size.y = (unsigned int)(y / 2);
}
// This is to store the occupying tiles
// Limits to store 4 tiles at a tile,
// Thus the size of the entity cannot be larger than the tile
typedef struct _CTileCoord_t {
unsigned int tiles[8];
unsigned int n_tiles;
} CTileCoord_t;
struct Entity {
Vector2 position;
@ -271,7 +100,7 @@ enum EntityUpdateEvent
struct EntityUpdateEventInfo
{
unsigned long e_id;
ComponentEnum_t comp_type;
unsigned int comp_type;
unsigned long c_id;
enum EntityUpdateEvent evt_type;
};
@ -299,8 +128,8 @@ Entity_t* add_entity(EntityManager_t* p_manager, unsigned int tag);
void remove_entity(EntityManager_t* p_manager, unsigned long id);
Entity_t *get_entity(EntityManager_t* p_manager, unsigned long id);
void* add_component(Entity_t *entity, ComponentEnum_t comp_type);
void* get_component(Entity_t *entity, ComponentEnum_t comp_type);
void remove_component(Entity_t* entity, ComponentEnum_t comp_type);
void* add_component(Entity_t *entity, unsigned int comp_type);
void* get_component(Entity_t *entity, unsigned int comp_type);
void remove_component(Entity_t* entity, unsigned int comp_type);
#endif // __ENTITY_H

View File

@ -4,7 +4,7 @@
#include "EC.h"
#include "raylib.h"
#include "rres.h"
#include "particle_sys.h"
#define N_ASSETS_TYPE 6
typedef enum AssetType
{
@ -16,6 +16,24 @@ typedef enum AssetType
AST_EMITTER_CONF,
}AssetType_t;
typedef enum PartEmitterType
{
EMITTER_UNKNOWN = 0,
EMITTER_BURST,
EMITTER_STREAM,
} PartEmitterType_t;
typedef struct EmitterConfig
{
float launch_range[2];
float speed_range[2];
float angle_range[2];
float rotation_range[2];
float particle_lifetime[2];
float initial_spawn_delay;
PartEmitterType_t type;
bool one_shot;
}EmitterConfig_t;
typedef struct Assets
{
@ -49,6 +67,18 @@ typedef struct LevelPack
LevelMap_t* levels;
}LevelPack_t;
// Credits to bedroomcoders.co.uk for this
typedef struct Sprite {
Texture2D* texture;
Vector2 frame_size;
Vector2 origin; // TL of the frame
Vector2 anchor; // Where transformation anchors on
uint8_t frame_per_row;
int frame_count;
int speed;
char* name;
} Sprite_t;
typedef struct RresFileInfo
{
rresCentralDir dir;

View File

@ -144,7 +144,7 @@ Entity_t* get_entity(EntityManager_t* p_manager, unsigned long id)
return p_entity;
}
void* add_component(Entity_t* p_entity, ComponentEnum_t comp_type)
void* add_component(Entity_t* p_entity, unsigned int comp_type)
{
if (p_entity->components[comp_type] == MAX_COMP_POOL_SIZE)
{
@ -163,7 +163,7 @@ void* add_component(Entity_t* p_entity, ComponentEnum_t comp_type)
return get_component(p_entity, comp_type);
}
void* get_component(Entity_t *p_entity, ComponentEnum_t comp_type)
void* get_component(Entity_t *p_entity, unsigned int comp_type)
{
unsigned long comp_type_idx = (unsigned long)comp_type;
unsigned long c_idx = p_entity->components[comp_type_idx];
@ -171,7 +171,7 @@ void* get_component(Entity_t *p_entity, ComponentEnum_t comp_type)
return get_component_wtih_id(comp_type, c_idx);
}
void remove_component(Entity_t *p_entity, ComponentEnum_t comp_type)
void remove_component(Entity_t *p_entity, unsigned int comp_type)
{
if (p_entity->components[comp_type] == MAX_COMP_POOL_SIZE) return;
struct EntityUpdateEventInfo evt = (struct EntityUpdateEventInfo){p_entity->m_id, comp_type, p_entity->components[comp_type] , COMP_DELETION};

View File

@ -134,7 +134,7 @@ void free_entity_to_mempool(unsigned long idx)
}
}
void* new_component_from_mempool(ComponentEnum_t comp_type, unsigned long* idx)
void* new_component_from_mempool(unsigned int comp_type, unsigned long* idx)
{
void* comp = NULL;
assert(comp_type < N_COMPONENTS);
@ -147,7 +147,7 @@ void* new_component_from_mempool(ComponentEnum_t comp_type, unsigned long* idx)
return comp;
}
void* get_component_wtih_id(ComponentEnum_t comp_type, unsigned long idx)
void* get_component_wtih_id(unsigned int comp_type, unsigned long idx)
{
void * comp = NULL;
assert(comp_type < N_COMPONENTS);
@ -158,7 +158,7 @@ void* get_component_wtih_id(ComponentEnum_t comp_type, unsigned long idx)
return comp;
}
void free_component_to_mempool(ComponentEnum_t comp_type, unsigned long idx)
void free_component_to_mempool(unsigned int comp_type, unsigned long idx)
{
assert(comp_type < N_COMPONENTS);
// This just free the component from the memory pool

View File

@ -20,15 +20,16 @@ typedef struct MemPool {
ULongCircBuffer_t free_list;
} MemPool_t;
// Game needs to implement this somewhere
extern MemPool_t comp_mempools[N_COMPONENTS];
Entity_t* new_entity_from_mempool(unsigned long* e_idx_ptr);
Entity_t* get_entity_wtih_id(unsigned long idx);
void free_entity_to_mempool(unsigned long idx);
void* new_component_from_mempool(ComponentEnum_t comp_type, unsigned long* idx);
void* get_component_wtih_id(ComponentEnum_t comp_type, unsigned long idx);
void free_component_to_mempool(ComponentEnum_t comp_type, unsigned long idx);
void* new_component_from_mempool(unsigned int comp_type, unsigned long* idx);
void* get_component_wtih_id(unsigned int comp_type, unsigned long idx);
void free_component_to_mempool(unsigned int comp_type, unsigned long idx);
void print_mempool_stats(char* buffer);
uint32_t get_num_of_free_entities(void);

View File

@ -3,16 +3,11 @@
#include "raylib.h"
#include "engine_conf.h"
#include "sc_queue.h"
#include "EC.h"
#include "assets.h"
#include <stdint.h>
#include <stdbool.h>
typedef enum PartEmitterType
{
EMITTER_UNKNOWN = 0,
EMITTER_BURST,
EMITTER_STREAM,
} PartEmitterType_t;
typedef uint16_t EmitterHandle;
typedef struct Particle
{
@ -32,18 +27,6 @@ typedef struct ParticleEmitter ParticleEmitter_t;
typedef void (*particle_update_func_t)(Particle_t* part, void* user_data, float delta_time);
typedef bool (*emitter_check_func_t)(const ParticleEmitter_t* emitter, float delta_time);
typedef struct EmitterConfig
{
float launch_range[2];
float speed_range[2];
float angle_range[2];
float rotation_range[2];
float particle_lifetime[2];
float initial_spawn_delay;
PartEmitterType_t type;
bool one_shot;
}EmitterConfig_t;
struct ParticleEmitter
{
const EmitterConfig_t* config;

173
scenes/components.h 100644
View File

@ -0,0 +1,173 @@
#include "EC.h"
#include "particle_sys.h" // includes assets
enum ComponentEnum {
CMOVEMENTSTATE_T = N_BASIC_COMPS,
CJUMP_COMP_T,
CPLAYERSTATE_T,
CCONTAINER_T,
CHITBOXES_T,
CHURTBOX_T,
CSPRITE_T,
CMOVEABLE_T,
CLIFETIMER_T,
CWATERRUNNER_T,
CAIRTIMER_T,
CEMITTER_T,
};
typedef struct _CMovementState_t {
uint8_t ground_state;
uint8_t water_state;
uint8_t x_dir;
float water_overlap;
} CMovementState_t;
typedef struct _CJump_t {
int jump_speed;
uint8_t jumps;
uint8_t max_jumps;
uint8_t coyote_timer;
bool jumped;
bool jump_ready;
bool short_hop;
bool jump_released;
} CJump_t;
typedef enum PlayerState {
GROUNDED,
AIR,
} PlayerState_t;
typedef struct _CPlayerState_t {
Vector2 player_dir;
uint8_t jump_pressed;
uint8_t is_crouch;
bool ladder_state;
bool locked; // Whether to respond to inputs
} CPlayerState_t;
typedef enum ContainerItem {
CONTAINER_EMPTY,
CONTAINER_LEFT_ARROW,
CONTAINER_RIGHT_ARROW,
CONTAINER_UP_ARROW,
CONTAINER_DOWN_ARROW,
CONTAINER_COIN,
CONTAINER_BOMB,
CONTAINER_EXPLOSION,
} ContainerItem_t;
typedef enum ContainerMaterial {
WOODEN_CONTAINER,
METAL_CONTAINER,
} ContainerMaterial_t;
typedef struct _CContainer_t {
ContainerMaterial_t material;
ContainerItem_t item;
} CContainer_t;
typedef struct _CHitBoxes_t {
Rectangle boxes[2];
uint8_t n_boxes;
uint8_t atk;
bool one_hit;
} CHitBoxes_t;
typedef struct _CHurtbox_t {
Vector2 offset;
Vector2 size;
uint8_t def;
unsigned int damage_src;
} CHurtbox_t;
typedef struct _CLifeTimer_t {
float life_time;
} CLifeTimer_t;
typedef struct _CAirTimer_t {
float max_ftimer;
float curr_ftimer;
float decay_rate;
uint8_t max_count;
uint8_t curr_count;
} CAirTimer_t;
typedef struct _BFSTile {
int32_t to;
int32_t from;
bool reachable;
}BFSTile_t;
typedef struct _BFSTileMap {
BFSTile_t* tilemap;
int32_t width;
int32_t height;
int32_t len;
}BFSTileMap_t;
typedef enum _WaterRunnerState
{
BFS_RESET = 0,
BFS_START,
LOWEST_POINT_SEARCH,
LOWEST_POINT_MOVEMENT,
REACHABILITY_SEARCH,
SCANLINE_FILL,
FILL_COMPLETE,
}WaterRunerState_t;
typedef struct _CWaterRunner {
BFSTileMap_t bfs_tilemap;
WaterRunerState_t state;
struct sc_queue_32 bfs_queue;
bool* visited;
int32_t current_tile;
int32_t target_tile;
int32_t fill_idx;
int16_t fill_range[2];
uint8_t movement_delay;
int8_t movement_speed;
int16_t counter;
float fractional;
}CWaterRunner_t;
typedef unsigned int (*sprite_transition_func_t)(Entity_t *ent); // Transition requires knowledge of the entity
typedef struct _SpriteRenderInfo
{
Sprite_t* sprite;
Vector2 offset;
AnchorPoint_t src_anchor;
AnchorPoint_t dest_anchor;
} SpriteRenderInfo_t;
typedef struct _CSprite_t {
SpriteRenderInfo_t* sprites;
sprite_transition_func_t transition_func;
unsigned int current_idx;
bool flip_x;
bool flip_y;
bool pause;
int current_frame;
float fractional;
float rotation; // Degree
float rotation_speed; // Degree / s
int elapsed;
Vector2 offset;
Color colour;
} CSprite_t;
typedef struct _CMoveable_t {
uint16_t move_speed;
Vector2 prev_pos;
Vector2 target_pos;
bool gridmove;
} CMoveable_t;
typedef struct _CEmitter_t
{
EmitterHandle handle;
Vector2 offset;
} CEmitter_t;

View File

@ -1,4 +1,6 @@
#include "mempool.h"
#include "components.h"
// Static allocate buffers
static CBBox_t bbox_buffer[MAX_COMP_POOL_SIZE];
static CTransform_t ctransform_buffer[MAX_COMP_POOL_SIZE];

View File

@ -1,7 +1,7 @@
#ifndef __ENT_IMPL_H
#define __ENT_IMPL_H
#include "assets.h"
#include "assets_tag.h"
#include "components.h"
bool init_player_creation(const char* info_file, Assets_t* assets);
bool init_player_creation_rres(const char* rres_file, const char* file, Assets_t* assets);