solstice

Compute collected power and efficiencies of a solar plant
git clone git://git.meso-star.com/solstice.git
Log | Files | Refs | README | LICENSE

commit 3eedd7eff4a70c4157e18034746e043ad283ba36
parent edf036b756c26b45ebf4576c08cd034e28d5c440
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 17 Nov 2016 13:25:31 +0100

Load the entity name

Build a per entity hash table in order to map an entity name to its
corresponding in memory representation.

Diffstat:
Msrc/solstice.c | 7+------
Msrc/solstice_entity.h | 39+++++++++++++++++++++++++++++++++++++--
Msrc/solstice_parser.c | 94++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
3 files changed, 117 insertions(+), 23 deletions(-)

diff --git a/src/solstice.c b/src/solstice.c @@ -35,8 +35,6 @@ main(int argc, char** argv) if(res != RES_OK) goto error; FOR_EACH(i, 1, argc) { - int is_empty = 1; - file = fopen(argv[i], "rb"); if(!file) { fprintf(stderr, "Could not open the file `%s'.\n", argv[i]); @@ -48,12 +46,8 @@ main(int argc, char** argv) do { res = solstice_parser_load(parser); - if(res != RES_BAD_OP) is_empty = 0; } while(res != RES_BAD_OP); - if(is_empty) { - fprintf(stderr, "The `%s' file seems empty.\n", argv[i]); - } fclose(file); file = NULL; } @@ -66,3 +60,4 @@ error: err = -1; goto exit; } + diff --git a/src/solstice_entity.h b/src/solstice_entity.h @@ -21,7 +21,9 @@ #include <rsys/double3.h> #include <rsys/dynamic_array.h> +#include <rsys/hash_table.h> #include <rsys/list.h> +#include <rsys/str.h> struct solstice_entity_id { size_t i; }; @@ -29,11 +31,26 @@ struct solstice_entity_id { size_t i; }; #define DARRAY_DATA struct solstice_entity_id #include <rsys/dynamic_array.h> +/* Declare the hash table that map an entity name to the index of its in memory + * solstice representation. */ +#define HTABLE_NAME str2sols +#define HTABLE_KEY struct str +#define HTABLE_KEY_FUNCTOR_INIT str_init +#define HTABLE_KEY_FUNCTOR_RELEASE str_release +#define HTABLE_KEY_FUNCTOR_COPY str_copy +#define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release +#define HTABLE_KEY_FUNCTOR_EQ str_eq +#define HTABLE_KEY_FUNCTOR_HASH str_hash +#define HTABLE_DATA size_t +#include <rsys/hash_table.h> + struct solstice_entity { double rotation[3]; double translation[3]; + struct str name; struct solstice_geometry_id geometry; + struct htable_str2sols str2children; struct darray_child children; /* List of children nodes */ }; @@ -45,6 +62,8 @@ solstice_entity_init d3_splat(entity->rotation, 0); d3_splat(entity->translation, 0); entity->geometry.i = SIZE_MAX; + str_init(allocator, &entity->name); + htable_str2sols_init(allocator, &entity->str2children); darray_child_init(allocator, &entity->children); } @@ -52,6 +71,8 @@ static INLINE void solstice_entity_release(struct solstice_entity* entity) { ASSERT(entity); + str_release(&entity->name); + htable_str2sols_release(&entity->str2children); darray_child_release(&entity->children); } @@ -59,22 +80,36 @@ static INLINE res_T solstice_entity_copy (struct solstice_entity* dst, const struct solstice_entity* src) { + res_T res = RES_OK; ASSERT(dst && src); d3_set(dst->translation, src->translation); d3_set(dst->rotation, src->rotation); dst->geometry = src->geometry; - return darray_child_copy(&dst->children, &src->children); + res = str_copy(&dst->name, &src->name); + if(res != RES_OK) return res; + res = htable_str2sols_copy(&dst->str2children, &src->str2children); + if(res != RES_OK) return res; + res = darray_child_copy(&dst->children, &src->children); + if(res != RES_OK) return res; + return RES_OK; } static INLINE res_T solstice_entity_copy_and_release (struct solstice_entity* dst, struct solstice_entity* src) { + res_T res = RES_OK; ASSERT(dst && src); d3_set(dst->translation, src->translation); d3_set(dst->rotation, src->rotation); dst->geometry = src->geometry; - return darray_child_copy_and_release(&dst->children, &src->children); + res = str_copy_and_release(&dst->name, &src->name); + if(res != RES_OK) return res; + res = htable_str2sols_copy_and_release(&dst->str2children, &src->str2children); + if(res != RES_OK) return res; + res = darray_child_copy_and_release(&dst->children, &src->children); + if(res != RES_OK) return res; + return RES_OK; } #endif /* SOLSTICE_ENTITY_H */ diff --git a/src/solstice_parser.c b/src/solstice_parser.c @@ -165,6 +165,7 @@ struct solstice_parser { /* Entity */ struct htable_yaml2sols yaml2entities; /* Cache of entities */ + struct htable_str2sols str2entities; struct darray_entity entities; /* Miscellaneous */ @@ -179,6 +180,7 @@ parse_entity (struct solstice_parser* parser, yaml_document_t* doc, yaml_node_t* entity, + struct htable_str2sols* htable, struct solstice_entity_id* solent); static res_T @@ -257,6 +259,7 @@ parser_clear(struct solstice_parser* parser) /* Tree */ htable_yaml2sols_clear(&parser->yaml2entities); + htable_str2sols_clear(&parser->str2entities); darray_entity_clear(&parser->entities); /* Miscellaneous */ @@ -300,6 +303,7 @@ parser_release(ref_T* ref) /* Tree */ htable_yaml2sols_release(&parser->yaml2entities); + htable_str2sols_release(&parser->str2entities); darray_entity_release(&parser->entities); /* Instance */ @@ -1927,15 +1931,47 @@ error: * Entity ******************************************************************************/ static res_T +entity_register_name + (struct solstice_parser* parser, + const yaml_node_t* entity, + struct htable_str2sols* htable, + const size_t isolent) +{ + struct solstice_entity* solent; + size_t* pisolent; + res_T res = RES_OK; + ASSERT(parser && htable); + ASSERT(isolent < darray_entity_size_get(&parser->entities)); + + solent = darray_entity_data_get(&parser->entities) + isolent; + + pisolent = htable_str2sols_find(htable, &solent->name); + if(pisolent) { + log_err(parser, entity, + "an entity with the name `%s' is already defined in the current context.\n", + str_cget(&solent->name)); + return RES_BAD_ARG; + } + + res = htable_str2sols_set(htable, &solent->name, &isolent); + if(res != RES_OK) { + log_err(parser, entity, "could not register the entity.\n"); + return res; + } + return RES_OK; +} + +static res_T parse_children (struct solstice_parser* parser, yaml_document_t* doc, const yaml_node_t* children, + struct htable_str2sols* htable, struct darray_child* entities) { intptr_t i, n; res_T res = RES_OK; - ASSERT(doc && children && entities); + ASSERT(doc && children && htable && entities); if(children->type != YAML_SEQUENCE_NODE) { log_err(parser, children, "expect a list of entities.\n"); @@ -1955,7 +1991,7 @@ parse_children yaml_node_t* child; child = yaml_document_get_node(doc, children->data.sequence.items.start[i]); - res = parse_entity(parser, doc, child, entity_id); + res = parse_entity(parser, doc, child, htable, entity_id); if(res != RES_OK) goto error; } @@ -1971,6 +2007,7 @@ parse_entity (struct solstice_parser* parser, yaml_document_t* doc, yaml_node_t* entity, + struct htable_str2sols* htable, struct solstice_entity_id* out_isolent) { enum { CHILDREN, DATA, NAME, TRANSFORM }; @@ -1979,12 +2016,15 @@ parse_entity size_t isolent = SIZE_MAX; intptr_t i, n; int mask = 0; /* Register the parsed attributes */ + int cp = 0; /* Defined whether or not the parsed entity was a copy */ res_T res = RES_OK; - ASSERT(doc && entity && out_isolent); + ASSERT(doc && entity && htable && out_isolent); pisolent = htable_yaml2sols_find(&parser->yaml2entities, &entity); if(pisolent) { isolent = *pisolent; + res = entity_register_name(parser, entity, htable, *pisolent); + if(res != RES_OK) goto error; goto exit; } @@ -2027,12 +2067,14 @@ parse_entity } (void)0 if(!strcmp((char*)key->data.scalar.value, "children")) { SETUP_MASK(CHILDREN, "children"); - res = parse_children(parser, doc, val, &solent->children); + res = parse_children + (parser, doc, val, &solent->str2children, &solent->children); } else if(!strcmp((char*)key->data.scalar.value, "geometry")) { SETUP_MASK(DATA, "data"); res = parse_geometry(parser, doc, val, &solent->geometry); } else if(!strcmp((char*)key->data.scalar.value, "name")) { - SETUP_MASK(NAME, "name"); /* TODO parse the entity name */ + SETUP_MASK(NAME, "name"); + res = parse_string(parser, val, &solent->name); } else if(!strcmp((char*)key->data.scalar.value, "pivot")) { SETUP_MASK(DATA, "data"); res = parse_pivot(parser, doc, val); @@ -2040,6 +2082,21 @@ parse_entity SETUP_MASK(TRANSFORM, "transform"); res = parse_transform (parser, doc, val, solent->translation, solent->rotation); + } else if(!strcmp((char*)key->data.scalar.value, "<<")) { /* Copy */ + struct solstice_entity* cp_solent; + pisolent = htable_yaml2sols_find(&parser->yaml2entities, &val); + if(!pisolent) { + log_err(parser, val, "invalid entity alias.\n"); + res = RES_BAD_ARG; + goto error; + } + cp_solent = darray_entity_data_get(&parser->entities) + *pisolent; + res = solstice_entity_copy(solent, cp_solent); + if(res != RES_OK) { + log_err(parser, val, "could not copy the entity.\n"); + goto error; + } + cp = 1; } else { log_err(parser, key, "unknown entity parameter `%s'.\n", key->data.scalar.value); @@ -2050,15 +2107,20 @@ parse_entity #undef SETUP_MASK } - #define CHECK_PARAM(Flag, Name) \ - if(!(mask & BIT(Flag))) { \ - log_err(parser, entity, "the entity "Name" is missing.\n"); \ - res = RES_BAD_ARG; \ - goto error; \ - } (void)0 - CHECK_PARAM(DATA, "data"); - CHECK_PARAM(NAME, "name"); - #undef CHECK_PARAM + if(!cp) { + #define CHECK_PARAM(Flag, Name) \ + if(!(mask & BIT(Flag))) { \ + log_err(parser, entity, "the entity "Name" is missing.\n"); \ + res = RES_BAD_ARG; \ + goto error; \ + } (void)0 + CHECK_PARAM(DATA, "data"); + CHECK_PARAM(NAME, "name"); + #undef CHECK_PARAM + } + + res = entity_register_name(parser, entity, htable, isolent); + if(res != RES_OK) goto error; res = htable_yaml2sols_set(&parser->yaml2entities, &entity, &isolent); if(res != RES_OK) { @@ -2071,6 +2133,7 @@ exit: return res; error: if(solent) { + htable_str2sols_erase(htable, &solent->name); darray_entity_pop_back(&parser->entities); isolent = SIZE_MAX; } @@ -2502,7 +2565,7 @@ parse_item if(!strcmp((char*)key->data.scalar.value, "material")) { res = parse_material(parser, doc, val, &mtl2); } else if(!strcmp((char*)key->data.scalar.value, "entity")) { - res = parse_entity(parser, doc, val, &entity); + res = parse_entity(parser, doc, val, &parser->str2entities, &entity); } else if(!strcmp((char*)key->data.scalar.value, "geometry")) { res = parse_geometry(parser, doc, val, &geometry); } else if(!strcmp((char*)key->data.scalar.value, "sun")) { @@ -2568,6 +2631,7 @@ solstice_parser_create /* Tree */ htable_yaml2sols_init(mem_allocator, &parser->yaml2entities); + htable_str2sols_init(mem_allocator, &parser->str2entities); darray_entity_init(mem_allocator, &parser->entities); /* Miscellaneous */