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:
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 */