Changed Config to read/write using new Parser and Parser_Objects

dev
Shariq Shah 8 years ago
parent 3354df46bb
commit 4c5bb465b1
  1. 6
      README.md
  2. 2
      build/genie.lua
  3. 11
      src/common/hashmap.c
  4. 1
      src/common/hashmap.h
  5. 11
      src/common/parser.c
  6. 3
      src/common/parser.h
  7. 95
      src/game/config_vars.c
  8. 4
      src/game/main.c

@ -155,7 +155,8 @@
- ## TODO
- Change Config to read/write using new Parser logic
- Add array support to variant
- Read/Write keybindings using new parser object
- 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
- Implement sound/listener loading from scene file
@ -328,4 +329,5 @@
* 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
* Implmented writing to file through the new Parser and Parser_Objects
* Changed Config to read/write using new Parser and Parser_Objects

@ -11,6 +11,8 @@ solution "Symmetry"
buildoptions {"-Wall", "-std=c99", "`pkg-config --cflags-only-I sdl2`"}
configuration {"windows", "gmake"}
postbuildcommands {"rm -rf debug/assets"}
postbuildcommands {"rm -rf release/assets"}
postbuildcommands {"ln -fs " .. os.getcwd() .. "/../assets debug/assets"}
postbuildcommands {"ln -fs " .. os.getcwd() .. "/../assets release/assets"}
buildoptions {"-Wall", "-std=c99"}

@ -347,3 +347,14 @@ int hashmap_iter_next(struct Hashmap* hashmap, char** key, struct Variant** valu
}
return 0;
}
void hashmap_copy(struct Hashmap* from, struct Hashmap* to)
{
struct Variant* from_val = NULL;
char* from_key = NULL;
HASHMAP_FOREACH(from, from_key, from_val)
{
hashmap_value_set(to, from_key, from_val);
}
}

@ -13,6 +13,7 @@ struct Variant;
struct Hashmap* hashmap_new(void);
void hashmap_free(struct Hashmap* hashmap);
void hashmap_copy(struct Hashmap* from, struct Hashmap* to);
void hashmap_value_remove(struct Hashmap* hashmap, const char* key);
bool hashmap_value_exists(struct Hashmap* hashmap, const char* key);
void hashmap_value_set(struct Hashmap* hashmap, const char* key, const struct Variant* value);

@ -13,9 +13,6 @@
#define MAX_LINE_LEN 512
#define MAX_VALUE_LEN 512
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)
{
if(!file)
@ -241,9 +238,10 @@ int parser_object_type_from_str(const char* str)
{
int object_type = PO_UNKNOWN;
if(strncmp(str, "Entity", HASH_MAX_KEY_LEN) == 0) object_type = PO_ENTITY;
else if(strncmp(str, "Model", HASH_MAX_KEY_LEN) == 0) object_type = PO_MODEL;
else if(strncmp(str, "Material", HASH_MAX_KEY_LEN) == 0) object_type = PO_MATERIAL;
if(strncmp(str, "Entity", HASH_MAX_KEY_LEN) == 0) object_type = PO_ENTITY;
else if(strncmp(str, "Model", HASH_MAX_KEY_LEN) == 0) object_type = PO_MODEL;
else if(strncmp(str, "Material", HASH_MAX_KEY_LEN) == 0) object_type = PO_MATERIAL;
else if(strncmp(str, "Config", HASH_MAX_KEY_LEN) == 0) object_type = PO_CONFIG;
return object_type;
}
@ -255,6 +253,7 @@ const char* parser_object_type_to_str(int type)
case PO_ENTITY: return "Entity";
case PO_MODEL: return "Model";
case PO_MATERIAL: return "Material";
case PO_CONFIG: return "Config";
case PO_UNKNOWN: return "Unknown";
default: return "Unknown";
}

@ -5,6 +5,7 @@
enum Parser_Object_Type
{
PO_CONFIG,
PO_ENTITY,
PO_MATERIAL,
PO_MODEL,
@ -30,5 +31,7 @@ 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);
int parser_object_type_from_str(const char* str);
const char* parser_object_type_to_str(int type);
#endif

@ -14,8 +14,6 @@
static struct Hashmap* cvars = NULL;
static void config_on_parser_assign(const char* key, const char* value, const char* filename, int current_line);
void config_vars_init(void)
{
cvars = hashmap_new();
@ -46,39 +44,53 @@ struct Hashmap* config_vars_get(void)
return cvars;
}
void config_on_parser_assign(const char* key, const char* value, const char* filename, int current_line)
{
struct Variant* cvar = hashmap_value_get(cvars, key);
if(!cvar)
{
log_warning("Unknown config key '%s' in file %s, line %d", key, filename, current_line);
return;
}
variant_from_str(cvar, value, cvar->type);
}
bool config_vars_load(const char* filename, int directory_type)
{
bool success = false;
FILE* config_file = io_file_open(directory_type, filename, "rb");
if(!config_file)
{
log_error("config:vars_load", "Could not open %s", filename);
return success;
return false;
}
if(!parser_load(config_file, filename, &config_on_parser_assign, false, 0))
{
log_error("config_vars:load", "Failed to parse config file %s", filename);
}
else
{
log_message("Loaded config from %s", filename);
success = true;
}
struct Parser* parser = parser_load_objects(config_file, filename);
if(!parser)
{
log_error("config_vars:load", "Failed to load config data from %s", filename);
fclose(config_file);
return false;
}
bool config_loaded = false;
for(int i = 0; i < array_len(parser->objects); i++)
{
struct Parser_Object* object = &parser->objects[i];
if(object->type != PO_CONFIG)
{
log_warning("Unexpected config object type %s in %s", parser_object_type_to_str(object->type), filename);
continue;
}
config_loaded = true;
char* key = NULL;
struct Variant* value = NULL;
char variant_str[MAX_VARIANT_STR_LEN];
HASHMAP_FOREACH(object->data, key, value)
{
struct Variant* existing_val = hashmap_value_get(cvars, key);
if(!existing_val)
{
log_warning("Unkown key '%s' in config file %s", key, filename);
continue;
}
variant_copy(existing_val, value);
}
}
if(config_loaded) log_message("Loaded config from %s", filename);
fclose(config_file);
return success;
return config_loaded;
}
bool config_vars_save(const char* filename, int directory_type)
@ -91,17 +103,32 @@ bool config_vars_save(const char* filename, int directory_type)
return success;
}
char* key = NULL;
struct Variant* value = NULL;
char variant_str[MAX_VARIANT_STR_LEN];
HASHMAP_FOREACH(cvars, key, value)
struct Parser* parser = parser_new();
if(!parser)
{
log_error("config_vars:save", "Could not create Parser for %s", filename);
fclose(config_file);
return false;
}
struct Parser_Object* object = parser_object_new(parser, PO_CONFIG);
if(!object)
{
log_error("config_vars:save", "Could not create Parser_Object for %s", filename);
parser_free(parser);
fclose(config_file);
return false;
}
hashmap_copy(cvars, object->data);
if(!parser_write_objects(parser, config_file, filename))
{
memset(variant_str, '\0', MAX_VARIANT_STR_LEN);
variant_to_str(value, variant_str, MAX_VARIANT_STR_LEN);
fprintf(config_file, "%s: %s\n", key, variant_str);
log_error("config_vars:save", "Failed to write config to '%s'", filename);
success = false;
}
log_message("Config file %s written.", filename);
success = true;
parser_free(parser);
fclose(config_file);
return success;
}

@ -176,10 +176,10 @@ bool init(void)
io_file_init(install_path, user_path);
free(install_path);
free(user_path);
if(!config_vars_load("config.cfg", DIRT_USER))
if(!config_vars_load("config.symtres", DIRT_USER))
{
log_error("main:init", "Could not load config, reverting to defaults");
config_vars_save("config.cfg", DIRT_USER);
config_vars_save("config.symtres", DIRT_USER);
}
if(!platform_init_video()) return false;

Loading…
Cancel
Save