#include #include #include #include #include #include #include "clay-layout.h" #include "clay-context.h" // todo: thread safety? maybe as an option CLAY_ENABLE_THREADSAFE struct clay_ctx_t { clay *layouts_ptrs; size_t layouts_length; size_t layouts_size; clay_property_desc_s *property_descs; size_t property_descs_length; size_t property_descs_size; int property_tag_cnt; }; clay_ctx clay_create_context(void) { clay_ctx ctx = malloc(sizeof *ctx); assert(ctx != NULL); ctx->layouts_size = 16; ctx->layouts_length = 0; ctx->layouts_ptrs = malloc(sizeof(*ctx->layouts_ptrs) * ctx->layouts_size); assert(ctx->layouts_ptrs != NULL); ctx->property_tag_cnt = 0; ctx->property_descs_size = 16; ctx->property_descs_length = 0; ctx->property_descs = malloc(sizeof(*ctx->property_descs) * ctx->property_descs_size); assert(ctx->property_descs != NULL); clay_text_register_props(ctx); clay_flex_register_props(ctx); clay_document_register_props(ctx); return ctx; } void clay_destroy_context(clay_ctx ctx) { // TODO: free everything owned by ctx for (size_t i = 0; i < ctx->layouts_length; ++i) { clay layout = ctx->layouts_ptrs[i]; clay_cleanup_layout(layout); free(layout); } free(ctx->layouts_ptrs); free(ctx->property_descs); free(ctx); } void clay_ctx_register_layout(clay_ctx ctx, clay layout) { assert(ctx->layouts_length <= ctx->layouts_size); if (ctx->layouts_length == ctx->layouts_size) { size_t new_size = ctx->layouts_size * 2; ctx->layouts_ptrs = realloc(ctx->layouts_ptrs, sizeof(*ctx->layouts_ptrs) * new_size); assert(ctx->layouts_ptrs != NULL); ctx->layouts_size = new_size; } ctx->layouts_length += 1; ctx->layouts_ptrs[ctx->layouts_length - 1] = layout; } void clay_ctx_unregister_layout(clay_ctx ctx, clay layout) { for (size_t i = 0; i < ctx->layouts_length; ++i) { if (ctx->layouts_ptrs[i] == layout) { ctx->layouts_ptrs[i] = ctx->layouts_ptrs[ctx->layouts_length - 1]; ctx->layouts_length -= 1; } } } int clay_ctx_register_property(clay_ctx ctx, const char *name, clay_property_type type) { assert (!clay_ctx_has_property(ctx, name)); int tag = ++ctx->property_tag_cnt; assert(ctx->property_descs_length <= ctx->property_descs_size); if (ctx->property_descs_length == ctx->property_descs_size) { size_t new_size = ctx->property_descs_size * 2; ctx->property_descs = realloc(ctx->property_descs, sizeof(*ctx->property_descs) * new_size); assert(ctx->property_descs != NULL); ctx->property_descs_size = new_size; } ctx->property_descs_length += 1; ctx->property_descs[ctx->property_descs_length - 1] = (clay_property_desc_s) { .type = type, .tag = tag, .name = name }; return tag; } void clay_ctx_unregister_property(clay_ctx ctx, int tag) { for (size_t i = 0; i < ctx->property_descs_length; ++i) { if (ctx->property_descs[i].tag == tag) { ctx->property_descs[i] = ctx->property_descs[ctx->property_descs_length - 1]; ctx->property_descs_length -= 1; return; } } } bool clay_ctx_has_property(clay_ctx ctx, const char *name) { for (size_t i = 0; i < ctx->property_descs_length; ++i) { if (strcmp(ctx->property_descs[i].name, name) == 0) { return true; } } return false; } clay_property_desc clay_ctx_get_property_desc(clay_ctx ctx, const char *name) { for (size_t i = 0; i < ctx->property_descs_length; ++i) { if (strcmp(ctx->property_descs[i].name, name) == 0) { return &ctx->property_descs[i]; } } return NULL; }