126 lines
3.8 KiB
C
126 lines
3.8 KiB
C
#include <clay.h>
|
|
#include <stddef.h>
|
|
#include <malloc.h>
|
|
#include <assert.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
|
|
#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;
|
|
}
|