From 3354df46bbaf1df6894bfe6cf2a5826d6b33a24d Mon Sep 17 00:00:00 2001 From: Shariq Shah Date: Fri, 13 Oct 2017 22:02:44 +0500 Subject: [PATCH] Implemented writing to files through the new Parser and Parser_Object intrerface --- README.md | 2 +- src/common/parser.c | 92 ++++++++- src/common/parser.h | 10 +- src/libsymmetry/entity.c | 424 ++++++--------------------------------- src/libsymmetry/entity.h | 2 +- src/libsymmetry/game.c | 4 +- src/libsymmetry/scene.c | 42 +++- src/libsymmetry/scene.h | 1 + 8 files changed, 196 insertions(+), 381 deletions(-) diff --git a/README.md b/README.md index 5d51cbb..08d7c26 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,6 @@ - ## TODO - - Implment writing to file through the new Parser and Parser_Object - Change Config to read/write using new Parser logic - Store Materials in new format supported by parser - Add model description file which has the same syntax supported by parser and modify old blender exporter to conform to new standards @@ -329,3 +328,4 @@ * Removed duplicate parsing logic * Fixed bugs in stripping key name for input map * Modify entity loading logic to use the new parsing code by parsing all entity properties into a hashmap first then recreating entity from that + * Implmented writing to file through the new Parser and Parser_Object diff --git a/src/common/parser.c b/src/common/parser.c index 60865e9..f0c6fce 100644 --- a/src/common/parser.c +++ b/src/common/parser.c @@ -1,5 +1,6 @@ #include "parser.h" #include "hashmap.h" +#include "variant.h" #include "array.h" #include "log.h" #include "string_utils.h" @@ -12,7 +13,8 @@ #define MAX_LINE_LEN 512 #define MAX_VALUE_LEN 512 -static int parser_object_type_from_str(const char* str); +static int parser_object_type_from_str(const char* str); +static const char* parser_object_type_to_str(int type); bool parser_load(FILE* file, const char* filename, Parser_Assign_Func assign_func, bool return_on_emptyline, int current_line) { @@ -88,7 +90,6 @@ struct Parser* parser_load_objects(FILE* file, const char* filename) return parser; } - parser->filename = str_new(filename); parser->objects = array_new(struct Parser_Object); int current_line = 0; @@ -215,7 +216,7 @@ struct Parser* parser_load_objects(FILE* file, const char* filename) if(strlen(line) == 0) { - continue; + continue; } if(line[0] == '#') @@ -247,14 +248,21 @@ int parser_object_type_from_str(const char* str) return object_type; } +const char* parser_object_type_to_str(int type) +{ + switch(type) + { + case PO_ENTITY: return "Entity"; + case PO_MODEL: return "Model"; + case PO_MATERIAL: return "Material"; + case PO_UNKNOWN: return "Unknown"; + default: return "Unknown"; + } +} + void parser_free(struct Parser *parser) { assert(parser); - if(parser->filename) - { - free(parser->filename); - parser->filename = NULL; - } for(int i = 0; i < array_len(parser->objects); i++) { @@ -264,3 +272,71 @@ void parser_free(struct Parser *parser) object->type = PO_UNKNOWN; } } + +struct Parser* parser_new(void) +{ + struct Parser* parser = NULL; + parser = malloc(sizeof(*parser)); + if(!parser) + { + log_error("parser:new", "Out of memory"); + return NULL; + } + + parser->objects = array_new(struct Parser_Object); + if(!parser->objects) + { + log_error("parser:new", "Could not create objects array for parser"); + free(parser); + return NULL; + } + + return parser; +} + +struct Parser_Object* parser_object_new(struct Parser* parser, int type) +{ + assert(parser); + struct Parser_Object* object = array_grow(parser->objects, struct Parser_Object); + if(!object) + { + log_error("parser:object_new", "Failed to add new parser object"); + return NULL; + } + object->type = type; + object->data = hashmap_new(); + + return object; +} + +bool parser_write_objects(struct Parser* parser, FILE* file, const char* filename) +{ + assert(parser); + char value_str[MAX_VALUE_LEN]; + int counter = 0; + for(int i = 0; i < array_len(parser->objects); i++) + { + struct Parser_Object* object = &parser->objects[i]; + if(object->type == PO_UNKNOWN) + { + log_warning("Unknown object type, cannot write to %s", filename); + continue; + } + + fprintf(file, "%s\n{\n", parser_object_type_to_str(object->type)); + + char* key = NULL; + struct Variant* value = NULL; + HASHMAP_FOREACH(object->data, key, value) + { + memset(value_str, '\0', MAX_VALUE_LEN); + variant_to_str(value, &value_str[0], MAX_VALUE_LEN); + fprintf(file, "\t%s : %s\n", key, value_str); + } + fprintf(file, "}\n\n"); + counter++; + } + + log_message("%d objects written to %s", counter, filename); + return true; +} diff --git a/src/common/parser.h b/src/common/parser.h index 4bf7b1e..70a9efe 100644 --- a/src/common/parser.h +++ b/src/common/parser.h @@ -19,14 +19,16 @@ struct Parser_Object struct Parser { - char* filename; struct Parser_Object* objects; }; typedef void (*Parser_Assign_Func)(const char* key, const char* value, const char* filename, int current_line); -bool parser_load(FILE* file, const char* filename, Parser_Assign_Func assign_func, bool return_on_emptyline, int current_line); -struct Parser* parser_load_objects(FILE* file, const char* filename); -void parser_free(struct Parser* parser); +bool parser_load(FILE* file, const char* filename, Parser_Assign_Func assign_func, bool return_on_emptyline, int current_line); +struct Parser* parser_load_objects(FILE* file, const char* filename); +void parser_free(struct Parser* parser); +struct Parser* parser_new(void); +struct Parser_Object* parser_object_new(struct Parser* parser, int type); +bool parser_write_objects(struct Parser* parser, FILE* file, const char* filename); #endif diff --git a/src/libsymmetry/entity.c b/src/libsymmetry/entity.c index a26564a..6acd1d5 100644 --- a/src/libsymmetry/entity.c +++ b/src/libsymmetry/entity.c @@ -9,6 +9,7 @@ #include "material.h" #include "geometry.h" #include "framebuffer.h" +#include "scene.h" #include "../common/variant.h" #include "../common/common.h" #include "../common/parser.h" @@ -199,64 +200,51 @@ struct Entity* entity_get_parent(int node) return parent; } -bool entity_write(struct Entity* entity, FILE* file) +bool entity_write(struct Entity* entity, struct Parser_Object* object) { - if(!file) + if(!object) { - log_error("entity:write", "Invalid file handle"); + log_error("entity:write", "Invalid object"); return false; } /* First write all properties common to all entity types */ - fprintf(file, "Entity\n{\n"); - fprintf(file, "\tname: %s\n", entity->name); - fprintf(file, "\ttype: %d\n", entity->type); - fprintf(file, "\tis_listener: %s\n", entity->is_listener ? "true" : "false"); - fprintf(file, "\trenderable: %s\n", entity->renderable ? "true" : "false"); + struct Hashmap* entity_data = object->data; + + hashmap_str_set(entity_data, "name", entity->name); + hashmap_int_set(entity_data, "type", entity->type); + hashmap_bool_set(entity_data, "is_listener", entity->is_listener); + hashmap_bool_set(entity_data, "renderable", entity->renderable); struct Entity* parent = entity_get_parent(entity->id); - fprintf(file, "\tparent: %s\n", parent ? parent->name : "NONE"); + hashmap_str_set(entity_data, "parent", parent ? parent->name : "NONE"); /* Transform */ - fprintf(file, "\tposition: %.5f %.5f %.5f\n", - entity->transform.position.x, - entity->transform.position.y, - entity->transform.position.z); - fprintf(file, "\tscale: %.5f %.5f %.5f\n", - entity->transform.scale.x, - entity->transform.scale.y, - entity->transform.scale.z); - fprintf(file, "\trotation: %.5f %.5f %.5f %.5f\n", - entity->transform.rotation.x, - entity->transform.rotation.y, - entity->transform.rotation.z, - entity->transform.rotation.w); - + hashmap_vec3_set(entity_data, "position", &entity->transform.position); + hashmap_vec3_set(entity_data, "scale", &entity->transform.scale); + hashmap_quat_set(entity_data, "rotation", &entity->transform.rotation); switch(entity->type) { case ET_CAMERA: { - fprintf(file, "\tortho: %s\n", entity->camera.ortho ? "true" : "false"); - fprintf(file, "\tresizeable: %s\n", entity->camera.resizeable ? "true" : "false"); - fprintf(file, "\tfov: %.5f\n", entity->camera.fov); - fprintf(file, "\tnearz: %.5f\n", entity->camera.nearz); - fprintf(file, "\tfarz: %.5f\n", entity->camera.farz); - fprintf(file, "\tclear_color: %.5f %.5f %.5f %.5f\n", - entity->camera.clear_color.x, - entity->camera.clear_color.y, - entity->camera.clear_color.z, - entity->camera.clear_color.w); + struct Camera* camera = &entity->camera; + hashmap_bool_set(entity_data, "ortho", camera->ortho); + hashmap_bool_set(entity_data, "resizeable", camera->resizeable); + hashmap_float_set(entity_data, "fov", camera->fov); + hashmap_float_set(entity_data, "nearz", camera->nearz); + hashmap_float_set(entity_data, "farz", camera->farz); + hashmap_vec4_set(entity_data, "clear_color", &camera->clear_color); if(entity->camera.fbo != -1) { - fprintf(file, "\thas_fbo: true\n"); - fprintf(file, "\tfbo_height: %d\n", framebuffer_height_get(entity->camera.fbo)); - fprintf(file, "\tfbo_width: %d\n", framebuffer_width_get(entity->camera.fbo)); - fprintf(file, "\tfbo_has_render_tex: %s\n", entity->camera.render_tex == -1 ? "false" : "true"); - fprintf(file, "\tfbo_has_depth_tex: %s\n", entity->camera.depth_tex == -1 ? "false" : "true"); + hashmap_bool_set(entity_data, "has_fbo", true); + hashmap_int_set(entity_data, "fbo_height", framebuffer_height_get(camera->fbo)); + hashmap_int_set(entity_data, "fbo_width", framebuffer_width_get(camera->fbo)); + hashmap_bool_set(entity_data, "fbo_has_render_tex", camera->render_tex == -1 ? false : true); + hashmap_bool_set(entity_data, "fbo_has_depth_tex", camera->depth_tex == -1 ? false : true); } else { - fprintf(file, "\thas_fbo: false\n"); + hashmap_bool_set(entity_data, "has_fbo", true); } break; } @@ -265,37 +253,34 @@ bool entity_write(struct Entity* entity, FILE* file) /* TODO: Change this after adding proper support for exported models from blender */ struct Material* material = material_get(entity->model.material); struct Geometry* geom = geom_get(entity->model.geometry_index); - fprintf(file, "\tmaterial: %s\n", material->name); - fprintf(file, "\tgeometry: %s\n", geom->filename); + hashmap_str_set(entity_data, "material", material->name); + hashmap_str_set(entity_data, "geometry", geom->filename); break; } case ET_LIGHT: { - fprintf(file, "\tlight_type: %d\n", entity->light.valid); - fprintf(file, "\touter_angle: %.5f\n", entity->light.outer_angle); - fprintf(file, "\tinner_angle: %.5f\n", entity->light.inner_angle); - fprintf(file, "\tfalloff: %.5f\n", entity->light.falloff); - fprintf(file, "\tradius: %d\n", entity->light.radius); - fprintf(file, "\tintensity: %.5f\n", entity->light.intensity); - fprintf(file, "\tdepth_bias: %.5f\n", entity->light.depth_bias); - fprintf(file, "\tvalid: %s\n", entity->light.valid ? "true" : "false"); - fprintf(file, "\tcast_shadow: %s\n", entity->light.cast_shadow ? "true" : "false"); - fprintf(file, "\tpcf_enabled: %s\n", entity->light.pcf_enabled ? "true" : "false"); - fprintf(file, "\tcolor: %.5f %.5f %.5f\n", - entity->light.color.x, - entity->light.color.y, - entity->light.color.z); + struct Light* light = &entity->light; + hashmap_int_set(entity_data, "light_type", light->type); + hashmap_float_set(entity_data, "outer_angle", light->outer_angle); + hashmap_float_set(entity_data, "inner_angle", light->inner_angle); + hashmap_float_set(entity_data, "falloff", light->falloff); + hashmap_float_set(entity_data, "radius", light->radius); + hashmap_float_set(entity_data, "intensity", light->intensity); + hashmap_float_set(entity_data, "depth_bias", light->depth_bias); + hashmap_bool_set(entity_data, "valid", light->valid); + hashmap_bool_set(entity_data, "cast_shadow", light->cast_shadow); + hashmap_bool_set(entity_data, "pcf_enabled", light->pcf_enabled); + hashmap_vec3_set(entity_data, "color", &light->color); break; } case ET_SOUND_SOURCE: { - fprintf(file, "\tactive: %s\n", entity->sound_source.active ? "true" : "false"); - fprintf(file, "\trelative: %s\n", entity->sound_source.relative ? "true" : "false"); + hashmap_bool_set(entity_data, "active", entity->sound_source.active); + hashmap_bool_set(entity_data, "relative", entity->sound_source.relative); break; } }; - fprintf(file, "}\n\n"); return true; } @@ -308,11 +293,19 @@ bool entity_save(struct Entity* entity, const char* filename, int directory_type return false; } - if(entity_write(entity, entity_file)) - log_message("Entity %s saved to %s", entity->name, filename); - else - log_error("entity:save", "Failed to save entity : %s to file : %s", entity->name, filename); + struct Parser* parser = parser_new(); + struct Parser_Object* object = parser_object_new(parser, PO_ENTITY); + if(!entity_write(entity, object)) + { + log_error("entity:save", "Failed to save entity : %s to file : %s", entity->name, filename); + fclose(entity_file); + return false; + } + if(parser_write_objects(parser, entity_file, filename)) + log_message("Entity %s saved to %s", entity->name, filename); + + parser_free(parser); fclose(entity_file); return false; } @@ -470,312 +463,17 @@ struct Entity* entity_read(struct Parser_Object* object) model_create(entity, geometry_name, material_name); } break; + case ET_ROOT: + { + scene_root_set(entity); + } + break; default: + log_warning("Unhandled Entity type '%d' detected", entity->type); break; } return entity; - - //struct Entity entity = - //{ - // .id = -1, - // .type = ET_NONE, - // .is_listener = false, - // .renderable = false, - // .marked_for_deletion = false, - // .name = "DEFAULT_ENTITY_NAME", - // .editor_selected = 0 - //}; - // - // int current_line = 0; - //char* material_name = NULL; - //char* entity_name = NULL; - //char* geometry_name = NULL; - //char* parent_name = NULL; - //int camera_fbo_width = -1; - //int camera_fbo_height = -1; - // char line_buffer[MAX_LINE_LEN]; - // char prop_str[MAX_ENTITY_PROP_NAME_LEN]; - //static struct Variant var_value = { .type = VT_NONE}; - - // variant_free(&var_value); - //memset(prop_str, '\0', MAX_ENTITY_PROP_NAME_LEN); - //memset(line_buffer, '\0', MAX_LINE_LEN); - - //while(fgets(line_buffer, MAX_LINE_LEN -1, file)) - //{ - // current_line++; - // memset(prop_str, '\0', MAX_ENTITY_PROP_NAME_LEN); - - // if(line_buffer[0] == '#') continue; - // if(strlen(line_buffer) == 0 || isspace(line_buffer[0])) break; - - // char* value_str = strstr(line_buffer, ":"); - // if(!value_str) - // { - // log_warning("Malformed value in line %d", current_line); - // continue; - // } - - // value_str++; /* Ignore the colon(:) and set the pointer after it */ - // - // if(sscanf(line_buffer, " %1024[^: ] : %*s", prop_str) != 1) - // { - // log_warning("Unable to read property name in line %d", current_line); - // continue; - // } - - // /* Common entity properties */ - // if(strncmp("name", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_STR); - // entity_name = str_new(var_value.val_str); - // //variant_copy_out(&entity.name, &var_value); - // } - // else if(strncmp("parent", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_STR); - // parent_name = str_new(var_value.val_str); - // //variant_copy_out(&entity.name, &var_value); - // } - // else if(strncmp("type", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_INT); - // variant_copy_out(&entity.type, &var_value); - // } - // else if(strncmp("is_listener", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_BOOL); - // variant_copy_out(&entity.is_listener, &var_value); - // } - // else if(strncmp("renderable", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_BOOL); - // variant_copy_out(&entity.renderable, &var_value); - // } - // - // /* Transform */ - // else if(strncmp("position", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_VEC3); - // variant_copy_out(&entity.transform.position, &var_value); - // } - // else if(strncmp("scale", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_VEC3); - // variant_copy_out(&entity.transform.scale, &var_value); - // } - // else if(strncmp("rotation", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_QUAT); - // variant_copy_out(&entity.transform.rotation, &var_value); - // } - - // /* Camera */ - // else if(strncmp("ortho", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_BOOL); - // variant_copy_out(&entity.camera.ortho, &var_value); - // } - // else if(strncmp("resizeable", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_BOOL); - // variant_copy_out(&entity.camera.resizeable, &var_value); - // } - // else if(strncmp("fov", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_FLOAT); - // variant_copy_out(&entity.camera.fov, &var_value); - // } - // else if(strncmp("nearz", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_FLOAT); - // variant_copy_out(&entity.camera.nearz, &var_value); - // } - // else if(strncmp("farz", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_FLOAT); - // variant_copy_out(&entity.camera.farz, &var_value); - // } - // else if(strncmp("has_fbo", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_BOOL); - // entity.camera.fbo = var_value.val_bool ? 0 : -1; - // } - // else if(strncmp("fbo_height", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_INT); - // variant_copy_out(&camera_fbo_height, &var_value); - // } - // else if(strncmp("fbo_width", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_INT); - // variant_copy_out(&camera_fbo_width, &var_value); - // } - // else if(strncmp("fbo_has_depth_tex", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_BOOL); - // entity.camera.depth_tex = var_value.val_bool ? 0 : -1; - // } - // else if(strncmp("fbo_has_render_tex", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_BOOL); - // entity.camera.render_tex = var_value.val_bool ? 0 : -1; - // } - // else if(strncmp("clear_color", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_VEC4); - // variant_copy_out(&entity.camera.clear_color, &var_value); - // } - - // /* Light */ - // else if(strncmp("light_type", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_INT); - // variant_copy_out(&entity.light.type, &var_value); - // } - // else if(strncmp("outer_angle", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_FLOAT); - // variant_copy_out(&entity.light.outer_angle, &var_value); - // } - // else if(strncmp("inner_angle", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_FLOAT); - // variant_copy_out(&entity.light.inner_angle, &var_value); - // } - // else if(strncmp("falloff", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_FLOAT); - // variant_copy_out(&entity.light.falloff, &var_value); - // } - // else if(strncmp("radius", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_INT); - // variant_copy_out(&entity.light.radius, &var_value); - // } - // else if(strncmp("intensity", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_FLOAT); - // variant_copy_out(&entity.light.intensity, &var_value); - // } - // else if(strncmp("depth_bias", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_FLOAT); - // variant_copy_out(&entity.light.depth_bias, &var_value); - // } - // else if(strncmp("valid", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_BOOL); - // variant_copy_out(&entity.light.valid, &var_value); - // } - // else if(strncmp("cast_shadow", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_BOOL); - // variant_copy_out(&entity.light.cast_shadow, &var_value); - // } - // else if(strncmp("pcf_enabled", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_BOOL); - // variant_copy_out(&entity.light.pcf_enabled, &var_value); - // } - // else if(strncmp("color", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_VEC3); - // variant_copy_out(&entity.light.color, &var_value); - // } - - // /* Model */ - // else if(strncmp("material", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_STR); - // material_name = str_new(var_value.val_str); - // } - // else if(strncmp("geometry", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_STR); - // geometry_name = str_new(var_value.val_str); - // } - - // /* Sound Source */ - // else if(strncmp("active", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_BOOL); - // variant_copy_out(&entity.sound_source.active, &var_value); - // } - // else if(strncmp("relative", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_BOOL); - // variant_copy_out(&entity.sound_source.relative, &var_value); - // } - // else if(strncmp("num_attached_buffers", prop_str, MAX_ENTITY_PROP_NAME_LEN) == 0) - // { - // variant_from_str(&var_value, value_str, VT_INT); - // variant_copy_out(&entity.sound_source.num_attached_buffers, &var_value); - // } - // else - // { - // log_warning("Unknown entity property '%s' in line %d", prop_str, current_line); - // } - - // variant_free(&var_value); - //} - - ///* Do the things after assignment */ - //struct Entity* parent_entity = NULL; - //if(strcmp(parent_name, "NONE") != 0) - // parent_entity = entity_find(parent_name); - // - //struct Entity* new_entity = entity_create(entity_name, entity.type, parent_entity ? parent_entity->id : -1); - //free(entity_name); - //transform_translate(new_entity, &entity.transform.position, TS_PARENT); - //quat_assign(&new_entity->transform.rotation, &entity.transform.rotation); - //transform_scale(new_entity, &entity.transform.scale); - // - //if(entity.renderable) new_entity->renderable = true; - // - //switch(new_entity->type) - //{ - //case ET_CAMERA: - // new_entity->camera.fbo = -1; - // new_entity->camera.depth_tex = -1; - // new_entity->camera.render_tex = -1; - // new_entity->camera.resizeable = false; - // new_entity->camera.nearz = entity.camera.nearz; - // new_entity->camera.farz = entity.camera.farz; - // new_entity->camera.ortho = entity.camera.ortho; - // new_entity->camera.fov = entity.camera.fov; - // float aspect_ratio = (float)camera_fbo_width / (float)camera_fbo_height; - // new_entity->camera.aspect_ratio = aspect_ratio <= 0.f ? (4.f / 3.f) : aspect_ratio; - // camera_update_view(new_entity); - // camera_update_proj(new_entity); - // if(entity.camera.fbo != -1) - // { - // camera_attach_fbo(new_entity, camera_fbo_width, camera_fbo_height, - // entity.camera.depth_tex == -1 ? false : true, - // entity.camera.render_tex == -1 ? false : true, - // entity.camera.resizeable); - // } - // vec4_assign(&new_entity->camera.clear_color, &entity.camera.clear_color); - // break; - //case ET_STATIC_MESH: - // model_create(new_entity, geometry_name, material_name); - // free(geometry_name); - // free(material_name); - // break; - //case ET_LIGHT: - // memcpy(&new_entity->light, &entity.light, sizeof(struct Light)); - // light_add(new_entity); - // break; - //case ET_SOUND_SOURCE: - // platform->sound.source_create(entity.sound_source.relative, - // entity.sound_source.num_attached_buffers, - // &new_entity->sound_source.source_handle, - // &new_entity->sound_source.buffer_handles[0]); - // break; - //}; - - //return new_entity; } bool entity_load(const char* filename, int directory_type) diff --git a/src/libsymmetry/entity.h b/src/libsymmetry/entity.h index 6315301..a1f203c 100644 --- a/src/libsymmetry/entity.h +++ b/src/libsymmetry/entity.h @@ -130,7 +130,7 @@ struct Entity* entity_get_all(void); struct Entity* entity_get_parent(int node); bool entity_save(struct Entity* entity, const char* filename, int directory_type); bool entity_load(const char* filename, int directory_type); -bool entity_write(struct Entity* entity, FILE* file); +bool entity_write(struct Entity* entity, struct Parser_Object* object); struct Entity* entity_read(struct Parser_Object* object); const char* entity_type_name_get(struct Entity* entity); diff --git a/src/libsymmetry/game.c b/src/libsymmetry/game.c index d27bb86..5d06cfb 100644 --- a/src/libsymmetry/game.c +++ b/src/libsymmetry/game.c @@ -210,11 +210,13 @@ void scene_setup(void) //struct Entity* light = entity_load("light.ent", DT_INSTALL); - if(scene_load("test.symtres", DIRT_INSTALL)) + if(scene_load("parser_write.symtres", DIRT_INSTALL)) { log_message("Scene loaded!"); struct Entity* player = entity_find("player"); game_state->player_node = player->id; + + //scene_save("parser_write.symtres", DIRT_INSTALL); } /* diff --git a/src/libsymmetry/scene.c b/src/libsymmetry/scene.c index 3fe2941..66447c1 100644 --- a/src/libsymmetry/scene.c +++ b/src/libsymmetry/scene.c @@ -4,6 +4,7 @@ #include "../common/log.h" #include "transform.h" #include "../common/common.h" +#include "../common/parser.h" #include #include @@ -101,6 +102,16 @@ struct Entity* scene_find(const char* name) struct Entity* scene_get_root(void) { return entity_get(root_node); +} + +void scene_root_set(struct Entity* entity) +{ + // Only use this function when we know the scene is empty and needs a root node. + // This is just a temporary way of setting root until we finalize how a scene should work + if(root_node == -1) + root_node = entity->id; + else + log_error("scene:root_set", "Scene already has a root node!"); } struct Entity* scene_get_child_by_name(struct Entity* parent, const char* name) @@ -175,6 +186,14 @@ bool scene_save(const char* filename, int directory_type) return false; } + struct Parser* parser = parser_new(); + if(!parser) + { + log_error("scene:save", "Could not create Parser"); + fclose(scene_file); + return false; + } + int* entities_to_write = array_new(int); array_push(entities_to_write, root_node, int); @@ -183,9 +202,16 @@ bool scene_save(const char* filename, int directory_type) while(!done) { struct Entity* entity = entity_get(entities_to_write[0]); - if(!entity_write(entity, scene_file)) + struct Parser_Object* object = parser_object_new(parser, PO_ENTITY); + if(!object) + { + log_error("scene:save", "Failed to create parser object for %s", entity->name); + continue; + } + + if(!entity_write(entity, object)) { - log_error("scene:save", "Failed to write '%s' to file", entity->name); + log_error("scene:save", "Failed to write '%s' into parser object", entity->name); continue; } @@ -198,8 +224,18 @@ bool scene_save(const char* filename, int directory_type) if(array_len(entities_to_write) == 0) done = true; } - log_message("%d entities written to %s", count, filename); + if(parser_write_objects(parser, scene_file, filename)) + { + log_message("%d entities written to %s", count, filename); + } + else + { + log_error("scene:save", "Failed to write scene to %s", filename); + success = false; + } + array_free(entities_to_write); + parser_free(parser); fclose(scene_file); return success; diff --git a/src/libsymmetry/scene.h b/src/libsymmetry/scene.h index 965e486..401747d 100644 --- a/src/libsymmetry/scene.h +++ b/src/libsymmetry/scene.h @@ -13,6 +13,7 @@ struct Entity* scene_add_new(const char* name, const int type); /* Add as child struct Entity* scene_add_as_child(const char* name, const int type, int parent); struct Entity* scene_find(const char* name); struct Entity* scene_get_root(void); +void scene_root_set(struct Entity* entity); struct Entity* scene_get_child_by_name(struct Entity* parent, const char* name); struct Entity* scene_get_parent(struct Entity* entity); bool scene_load(const char* filename, int directory_type);