#ifndef MT_SHADOW_TAG_H #define MT_SHADOW_TAG_H #include #include #include typedef struct MtShadowTag MtShadowTag; typedef struct MtShadowTagPool MtShadowTagPool; typedef struct MtShadowTagName MtShadowTagName; typedef struct MtShadowTagNameArena MtShadowTagNameArena; typedef struct MtShadowTagNameRegistry MtShadowTagNameRegistry; typedef struct MtShadowTagSystem MtShadowTagSystem; typedef enum { MT_SHADOW_TAG_INTEGER, MT_SHADOW_TAG_BOOLEAN, MT_SHADOW_TAG_DECIMAL, MT_SHADOW_TAG_STRING, MT_SHADOW_TAG_RAW_POINTER, MT_SHADOW_TAG_VECTOR_2, MT_SHADOW_TAG_VECTOR_3, MT_SHADOW_TAG_VECTOR_4, MT_SHADOW_TAG_SUB_ENTITY, MT_SHADOW_TAG_RESOURCE } MtShadowTagType; struct MtShadowTag { MtShadowTagPool *pool; MtShadowTag *next; MtShadowTagType type; u32_t name_identifier; union MtShadowTagData { bool_t boolean; i64_t integer; f64_t decimal; char *string; void *raw_pointer; rr_vec2f_s vec2f; rr_vec3f_s vec3f; rr_vec4f_s vec4f; MtEntity entity; } data; }; struct MtShadowTagPool { usz_t capacity; MtShadowTag *allocation; MtShadowTag *first_free; MtShadowTagPool *continuation; }; struct MtShadowTagNameArena { usz_t capacity; usz_t usage; char *allocation; MtShadowTagNameArena *continuation; }; struct MtShadowTagName { char *string_in_arena; u32_t identifier; }; struct MtShadowTagNameRegistry { usz_t names_capacity; usz_t num_names; MtShadowTagName *names; u32_t id_counter; MtShadowTagNameArena *root_arena; }; struct MtShadowTagSystem { MtShadowTagNameRegistry name_registry; MtShadowTagPool root_pool; }; void mt_init_shadow_tag_system(MtShadowTagSystem *tag_system); void mt_cleanup_shadow_tag_system(MtShadowTagSystem *tag_system); MtShadowTagPool * mt_new_shadow_tag_pool(usz_t capacity); /// @brief Crates a new MtShadowTagPool with a given capacity. /// @warning Don't use `mt_free_shadow_tag_pool()` with use created with this method. /// It will result in a call to `free()` for the given pool, which may cause a crash. /// @param pool A pointer to the location at which the pool should be created. /// @param capacity The number of entity shadow tags which should be able to reside in /// the first instance of the pool. The pool will allocate more once needed. void mt_init_shadow_tag_pool(MtShadowTagPool *pool, usz_t capacity); void mt_free_shadow_tag_pool(MtShadowTagPool *pool); MtShadowTag * mt_alloc_shadow_tag(void *context_ptr); MtShadowTag * mt_alloc_shadow_tag_in_pool(MtShadowTagPool *pool); /// @brief Crates as new MtShadowTag, makes it the new first of the chain given as input and /// returns the new chain start. The chain start should be set to the returned value /// @param chain_start The current start of the singly linked list of tags which are /// attached to a shadow (the start of the tag chain). /// @return The new tag chain's start. MtShadowTag * mt_alloc_shadow_tag_before(MtShadowTag *chain_start); void mt_free_shadow_tag_chain(MtShadowTag *tag); u32_t mt_tag_name_to_id(void *context_ptr, const char *tag_name); #endif // MT_SHADOW_TAG_H