#ifndef ENTITY_H #define ENTITY_H #include "sprite.h" #include "mixer.h" enum entity_prop { ENTITY_PROP_NONE, ENTITY_PROP_ANIMATING, ENTITY_PROP_PLAYER_CONTROLLED, ENTITY_PROP_CAMERA, ENTITY_PROP_CAMERA_ACTIVE, /* Test props */ ENTITY_PROP_TEST, ENTITY_PROP_TEST_SOUND_EMITTER, ENTITY_PROP_COUNT }; struct entity_handle { u64 idx; u64 gen; }; struct entity_store { struct arena arena; u64 count; struct entity_handle first_free; }; struct entity { b32 valid; struct entity_handle handle; u64 continuity_gen; u64 props[(ENTITY_PROP_COUNT + 63) / 64]; struct entity_handle next_free; /* Tree */ struct entity_handle parent; struct entity_handle next; struct entity_handle prev; struct entity_handle first; struct entity_handle last; /* ====================================================================== */ struct xform rel_xform; /* Transform in relation to parent entity (or the world if entity has no parent) */ struct xform world_xform; /* Calculated post-physics */ /* ====================================================================== */ /* Physics */ struct v2 acceleration; struct v2 velocity; /* ENTITY_PROP_PLAYER_CONTROLLED */ f32 player_max_speed; f32 player_acceleration; struct v2 player_aim; /* ====================================================================== */ /* Sprite */ struct sprite_tag sprite; struct string sprite_span_name; struct xform sprite_quad_xform; u32 sprite_tint; /* ====================================================================== */ /* Animation */ /* ENTITY_PROP_ANIMATING */ f64 animation_time_in_frame; u64 animation_frame; /* ====================================================================== */ /* Testing */ /* ENTITY_PROP_TEST */ b32 test_initialized; struct xform test_start_rel_xform; struct xform test_start_sprite_xform; /* ENTITY_PROP_TEST_SOUND_EMITTER */ struct string sound_name; struct mixer_desc sound_desc; struct mixer_track_handle sound_handle; /* ====================================================================== */ /* ENTITY_PROP_CAMERA */ struct entity_handle camera_follow; struct xform camera_quad_xform; f32 camera_lerp; /* Rate at which camera xform approaches target xform */ u32 camera_lerp_continuity_gen; struct xform camera_rel_xform_target; /* Calculated from camera_follow */ u32 camera_applied_lerp_continuity_gen_plus_one; /* Calculated */ }; struct entity_array { struct entity *entities; u64 count; }; struct entity_prop_array { enum entity_prop *props; u64 count; }; /* ========================== * * Nil * ========================== */ INLINE struct entity *entity_nil(void) { extern READONLY struct entity _g_entity_nil; return &_g_entity_nil; } /* ========================== * * Property helpers * ========================== */ INLINE void entity_enable_prop(struct entity *entity, enum entity_prop prop) { u64 index = prop / 64; u64 bit = prop % 64; entity->props[index] |= ((u64)1 << bit); } INLINE void entity_disable_prop(struct entity *entity, enum entity_prop prop) { u64 index = prop / 64; u64 bit = prop % 64; entity->props[index] &= ~((u64)1 << bit); } INLINE b32 entity_has_prop(struct entity *entity, enum entity_prop prop) { u64 index = prop / 64; u64 bit = prop % 64; return !!(entity->props[index] & ((u64)1 << bit)); } /* ========================== * * Entity functions * ========================== */ /* Entity store */ struct entity_store entity_store_alloc(void); void entity_store_release(struct entity_store *store); void entity_store_copy_replace(struct entity_store *dest, struct entity_store *src); /* Entity */ struct entity *entity_alloc(struct entity_store *store); void entity_release(struct entity_store *store, struct entity *entity); struct entity_array entity_store_as_array(struct entity_store *store); struct entity *entity_from_handle(struct entity_store *store, struct entity_handle handle); struct entity *entity_find_first_match_one(struct entity_store *store, enum entity_prop prop); struct entity *entity_find_first_match_all(struct entity_store *store, struct entity_prop_array props); void entity_link(struct entity_store *store, struct entity *parent, struct entity *child); #endif