89 lines
3.1 KiB
C
89 lines
3.1 KiB
C
//---
|
|
// entity: Varied objects in the game, implemented with components
|
|
//
|
|
// This game runs on an Entity-Component system. Entities uniquely identify a
|
|
// variety of game objects, ranging from players and enemies to skills' areas
|
|
// of effect, item drops, spawn regions...
|
|
//
|
|
// Entities themselves are fairly empty, and most of their properties are
|
|
// defined through components. For instance, the [physical] component assigns a
|
|
// in space and a hitbox; the [visible] component gives sprites and rendering
|
|
// properties; the [mechanical] component provides controlled motion.
|
|
//---
|
|
|
|
#pragma once
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <stdbool.h>
|
|
|
|
typedef struct
|
|
{
|
|
/* Deletion flag - deletions are delayed until end of frame to ease
|
|
management of dangling references */
|
|
uint32_t deleted: 1;
|
|
/* Bitmask of components in that entity (see ENTITY_COMP_*) */
|
|
uint32_t comps: 31;
|
|
/* Pointer to components; one pointer per non-zero entry in [comps],
|
|
starting from LSB to MSB */
|
|
void *data[];
|
|
|
|
} entity_t;
|
|
|
|
/* Bit field values for each type of component */
|
|
#define ENTITY_COMP_physical 0x00000001
|
|
#define ENTITY_COMP_visible 0x00000002
|
|
#define ENTITY_COMP_mechanical 0x00000004
|
|
#define ENTITY_COMP_fighter 0x00000008
|
|
#define ENTITY_COMP_aoe 0x00000010
|
|
#define ENTITY_COMP_particle 0x00000020
|
|
/* Maximum number of components */
|
|
#define ENTITY_COMP_CAPACITY 31
|
|
|
|
/* Get a component from an entity */
|
|
static inline void *getcomp(entity_t const *e, uint32_t comp)
|
|
{
|
|
if(__builtin_expect(!(e->comps & comp), 0))
|
|
return NULL;
|
|
|
|
int i = 0;
|
|
while(comp) i += (e->comps & (comp >>= 1)) != 0;
|
|
|
|
return e->data[i];
|
|
}
|
|
/* Write "getcomp(e, physical)" */
|
|
#define getcomp(e, comp) ((comp ## _t *)getcomp(e, ENTITY_COMP_ ## comp))
|
|
|
|
/* Create an entity with a fixed set of components */
|
|
entity_t *entity_make(uint32_t comp);
|
|
|
|
/* Variation of entity_make() with up to 6 variable arguments */
|
|
#define ENTITY_MAKE_ARGS1(type, ...) \
|
|
ENTITY_COMP_##type __VA_OPT__(| ENTITY_MAKE_ARGS(__VA_ARGS__))
|
|
#define ENTITY_MAKE_ARGS2(type, ...) \
|
|
ENTITY_COMP_##type __VA_OPT__(| ENTITY_MAKE_ARGS1(__VA_ARGS__))
|
|
#define ENTITY_MAKE_ARGS3(type, ...) \
|
|
ENTITY_COMP_##type __VA_OPT__(| ENTITY_MAKE_ARGS2(__VA_ARGS__))
|
|
#define ENTITY_MAKE_ARGS4(type, ...) \
|
|
ENTITY_COMP_##type __VA_OPT__(| ENTITY_MAKE_ARGS3(__VA_ARGS__))
|
|
#define ENTITY_MAKE_ARGS5(type, ...) \
|
|
ENTITY_COMP_##type __VA_OPT__(| ENTITY_MAKE_ARGS4(__VA_ARGS__))
|
|
#define ENTITY_MAKE_ARGS6(type, ...) \
|
|
ENTITY_COMP_##type __VA_OPT__(| ENTITY_MAKE_ARGS5(__VA_ARGS__))
|
|
#define entity_make(...) \
|
|
entity_make(ENTITY_MAKE_ARGS6(__VA_ARGS__))
|
|
|
|
/* Mark an entity for deletion at the next collection step */
|
|
void entity_mark_to_delete(entity_t *e);
|
|
|
|
/* Destroy an entity */
|
|
void entity_destroy(entity_t *e);
|
|
|
|
// Useful types when finding/filtering/sorting entities
|
|
|
|
/* Propositional predicate on entities; used for counting and filtering */
|
|
typedef bool entity_predicate_t(entity_t const *e);
|
|
|
|
/* Measure; used for filtering-sorting */
|
|
typedef int entity_measure_t(entity_t const *e);
|